Android学习笔记(八)深入分析Service启动、绑定过程

  Service是Android中一个重要的组件,它没有用户界面,可以运行在后太做一些耗时操作。Service可以被其他组件启动,甚至当用户切换到其他应用时,它仍然可以在后台保存运行。Service 是Android四大组件中与Activity最相似的组件,都代表可执行的程序,区别在于:Service一直运行在后台,没有界面,一旦Service被启动,即完全具有自己的生命周期。

一、创建一个Service

  在创建Service时,步骤与Activity很像:

  1.继承Service,创建Service子类。

  2.在AndroidManifest.xml文件中配置该Service。

下面创建一个最基本的Service组件:

MyService.java

 1 public class MyService extends Service {
 2     
 3     //必须实现的方法,用户返回Binder对象
 4     @Override
 5     public IBinder onBind(Intent intent) {
 6         System.out.println("--onBind()--");
 7         return null;
 8     }
 9     
10     //创建Service时调用该方法,只调用一次
11     @Override
12     public void onCreate() {
13         super.onCreate();
14         System.out.println("--onCreate()--");
15     }
16     
17     //每次启动Servcie时都会调用该方法
18     @Override
19     public int onStartCommand(Intent intent, int flags, int startId) {
20         System.out.println("--onStartCommand()--");
21         return super.onStartCommand(intent, flags, startId);
22     }
23     
24     //解绑Servcie调用该方法
25     @Override
26     public boolean onUnbind(Intent intent) {
27         System.out.println("--onUnbind()--");
28         return super.onUnbind(intent);
29     }
30     
31     //退出或者销毁时调用该方法
32     @Override
33     public void onDestroy() {
34         System.out.println("--onDestroy()--");
35         super.onDestroy();
36     }
37     
38 }

然后再Manifest.xml文件中红配置一下

1 <service 
2      android:name=".MyService">
3 </service>

 为了待会测试的方便,我们在该Service的onCreate()方法里面写一个方法,开启一个线程,让其不断输出“Service运行中”的状态。补充后的MyService类如下:

 1 public class MyService extends Service {
 2     
 3     private boolean serviceRunning = false;
 4     // 必须实现的方法,用户返回Binder对象
 5     @Override
 6     public IBinder onBind(Intent intent) {
 7         System.out.println("--onBind()--");
 8         return null;
 9     }
10 
11     // 创建Service时调用该方法,只调用一次
12     @Override
13     public void onCreate() {
14         super.onCreate();
15         System.out.println("--onCreate()--");
16         serviceRunning = true;
17         new Thread() {
18             @Override
19             public void run() {
20                 while (serviceRunning) {
21                     System.out.println("---Service运行中---");
22                     try {
23                         sleep(1000);
24                     } catch (InterruptedException e) {
25                         e.printStackTrace();
26                     }
27                 }
28             };
29         }.start();
30     }
31 
32     // 每次启动Servcie时都会调用该方法
33     @Override
34     public int onStartCommand(Intent intent, int flags, int startId) {
35         System.out.println("--onStartCommand()--");
36         return super.onStartCommand(intent, flags, startId);
37     }
38 
39     // 解绑Servcie调用该方法
40     @Override
41     public boolean onUnbind(Intent intent) {
42         System.out.println("--onUnbind()--");
43         return super.onUnbind(intent);
44     }
45 
46     // 退出或者销毁时调用该方法
47     @Override
48     public void onDestroy() {
49         serviceRunning = false;
50         System.out.println("--onDestroy()--");
51         super.onDestroy();
52     }
53 
54 }

代码分析:首先我们定义一个boolean类型的变量serviceRunning,用来控制新线程中是否输出“---Service运行中---”,通过这样的方式更能让我们直观地看到Servcie的运行状态。

二、启动Service

  启动Service和启动一个Activity类似,也是先定义一个Intent让它指向需要启动Service,然后通过调用startService()方法,启动即可,具体代码如下:

1 btn_start_service.setOnClickListener(new OnClickListener() {
2      @Override
3      public void onClick(View arg0) {
4          intent = new Intent(this, MyService.class);5          startService(intent);
6         }
7 });

 代码分析:在主界面中添加了一个按钮,在按钮中首先定义了一个Intent,然后通过startService启动该Intent从而就可以启动Service,与启动一个Activity的方法简直一样啊。

三、停止Service

  与启动Service相对应的就是停止Service,通过stopService()即可完成此操作,如下:

1 btn_stop_service.setOnClickListener(new OnClickListener() {
2      @Override
3      public void onClick(View arg0) {
4          stopService(intent);
5          }
6 });

 当然,这里Intent需要与startService使用的为一个。

四、绑定Service

  绑定Service用是通过调用bindService(Intent service, ServiceConnection conn, int flags)方法来实现的,单看参数就知道与启动Service比起来,会麻烦一些,大体分为如下三步:

第一步:重写onBind()方法,返回Service实例

  Service可以让Activity绑定,以获得更加详细的接口。如果先想让一个Service支持绑定,需要实现Service中得onBind()方法,并返回被绑定Service的当前实例,如下:

1     public IBinder onBind(Intent intent) {
2         System.out.println("--onBind()--");
3         return new MyBinder();
4     }
5     
6     public class MyBinder extends Binder{
7         MyService getService(){
8             return MyService.this;
9     }

第二步:实现一个ServiceConnection  

  另外,Service和其他组件的链接表示为一个ServiceConnection,要想一个Service和其他组件绑定,需要实现一个新的ServiceConnection,建立一个链接后,就可以通过重写onServiceConnected()方法和onServiceDisconnected()方法,来获得对Service实例的引用。代码如下:

 1 MyService.MyBinder binder = null;
 2 class MyServiceConn implements ServiceConnection {
 3         // 服务被绑定成功之后执行
 4         @Override
 5         public void onServiceConnected(ComponentName name, IBinder service) {
 6             //service为onBind方法返回的Service实例
 7             binder = (MyService.MyBinder) service;
 8         }
 9         
10         // 服务奔溃或者被杀掉执行
11         @Override
12         public void onServiceDisconnected(ComponentName name) {
13        binder = null;
14         }
15 }

 第三步:调用bindService执行绑定Service

  要想绑定需要给bindService()除了需要给他传递一个需要的Intent和一个ServiceConnection实例外,还需要指定一个标示,如下:

1 btn_bind_service.setOnClickListener(new OnClickListener() {
2             @Override
3             public void onClick(View arg0) {
4                 bindService(intent, myServiceConn, Context.BIND_AUTO_CREATE);
5             }
6 });

  其中,myServiceConn为第二步中MyServiceConn实例,Context.BIND_AUTO_CREATE即为标示。

五、解绑Service

  解绑Service是通过unbindService实现的,如下:

1 btn_unbind_service.setOnClickListener(new OnClickListener() {
2             @Override
3             public void onClick(View arg0) {
4                 if (binder != null) {
5                     unbindService(myServiceConn);
6                 }
7             }
8 });

  这里需要注意的是,unbindService方法中传入的ServiceConnection实例一定要跟绑定时的一致,否则可能会导致程序崩溃。

六、试验

  主界面简单,只有四个按钮,如下:

  1、当按下startService按钮,然后再按下stopService按钮时,日志如下:

  2、当按下bindService,然后再按下unbindService时,日志如下:

  3、当按下startService接着按bindService时,这时候就需要unbindService和stopService都按下后才能停止Service,日志如下:

七、总结

  启动Service和停止Service是一一对应的,绑定Service和解绑Servcie是一一对应的,如果同时启动和绑定了Service,必须通过解绑和停止Service才能使该Service真正停止。

声明:欢迎转载,转载时请注明本文链接。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏腾讯IVWEB团队的专栏

使用 Xposed 强制 androidwebView 开启 debug 模式

从 《远程调试 Android 设备使用入门》文章中我们可以知道在 android 4.4+可以通过在apk中使用下面的代码开启 webview 的 chrom...

70300
来自专栏腾讯移动品质中心TMQ的专栏

iOS 测试利器:idb

对于android的开发以及测试人员,对adb命令一定会很熟悉,adb工具可谓android测试的入门神器,安装、卸载、抓log、截图等等一应俱全。很多自动化以...

3.2K10
来自专栏Bennyhuo

用 Kotlin 写 Android ,难道只有环境搭建这么简单?

话说我们入坑 Kotlin 之后,要怎样才能把它运用到 Android 开发当中呢?我们作为有经验的开发人员,大家都知道 Android 现在基本上都用 gra...

5.8K00
来自专栏QQ会员技术团队的专栏

深入理解React(二) :数据流和事件原理

在React中,数据流是自上而下单向的从父节点传递到子节点,所以组件是简单且容易把握的,他们只需要从父节点提供的props中获取数据并渲染即可。如果顶层组件的某...

4.8K00
来自专栏应兆康的专栏

遇见 Kotlin 先导篇:Kotlin 相比 Java 好在哪里?

Kotlin 是一种为现代多平台应用而诞生的静态编程语言相比于Java而言,它有很多优点,待会笔者会就几个写一下,并给出实际例子。

50540
来自专栏Matthew

5分钟教你打造一个秒开的 Android App

近日在开发过程中,发现每次点击 app 从桌面启动都有一个在桌面明显的等待时间,机型越低端的越明显,冷启动优化看来已经势在必行,所以怒而一顿研究再解决之。

1.9K10
来自专栏QQ空间开发团队的专栏

RxJava && Agera 从源码简要分析基本调用流程(1)

相信很多做Android或是Java研发的同学对RxJava应该都早有耳闻了,尤其是在Android开发的圈子里,RxJava渐渐开始广为流行。同样有很多同学已...

8.6K10
来自专栏刘宁的专栏

Android开发入门的正确姿势

对于从事移动客户端开发者的初学者而言,不论是Android还是iOS开发,对客户端开发有一个整体的认识,然后再逐步深入,这样会有事半功倍的效果。

1.4K00
来自专栏腾讯移动品质中心TMQ的专栏

一种 Android 端 Web 多进程情况下支持 Web 自动化测试的方法

本文介绍一种在Web多进程情况下支持Web自动化测试的方案。介绍当前Web自动化的简要原理、Web多进程后的问题、相应的解决方案及使用方法。

40700
来自专栏QQ空间开发团队的专栏

RxJava && Agera 从源码简要分析基本调用流程(2)

RxJava能够帮助我们对数据流进行灵活的变换,以达到链式结构操作的目的,然而它的强大不止于此。下面我们就来看看它的又一利器,调度器`Scheduler`:就像...

9.3K10

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励