在上面几章我们了解了四大组件之一的Activity的一些使用,接下来我们继续来看看四大组件的另外一个,即Service(服务)。与Activity(活动)不同,Service是属于在后台服务的,即用户在界面是感知不到的。那么,为什么需要Service呢?我们知道,在android中,系统会为我们创建一个UI线程,也叫主线程,而主线程的主要任务就是做界面交互用的,不适合在UI线程做那些耗时的操作,否则会出现ANR的错误提醒,那么那些比较耗时的操作要怎么办呢?比如,读取文件数据,获取网络,数据库操作等等,一般这个时候只能开一个子线程来处理这些耗时的操作了,而Service正是为了解决这个问题而存在的。Service
主要用于在后台处理一些比较耗时的工作,那么Service到底是怎么工作的呢?我们先来看看Service的一些基本信息。
Service的生命周期:
1.png 2.png相对于activity,Service的生命周期所对应的方法就比较简单,总共的方法就那么几个,下面我们一一来解释一下:
(1)onCreate:在Service被开启的时候调用,表示服务正在被创建。
(2)onStartCommend:表示Service在运行。
(3)onStart:表示Service在运行,不过该方法已经被标记过时,所以不用太多去关注。
(4)onBind和onUnbind是一对运行方式,这里先不讲,后面再讲解。
(5)onDestroy:表示服务关闭。
先来看张图:
3.png
相信这张图很多童鞋都明白什么意思。其实开启服务的方式有两种,一种是startServie(),其完整的生命周期方法为:onCreate->onStartCommand->onDestroy,其中onCreate和onDestroy在整个的生命周期过程中只会被调用一次,而onStartCommand则会被调用多次。另外一种是bindSerive,其完整的生命周期的方法为:onCreate->onBind->onUnbind->onDestroy。下面来分别介绍一下这两种启动方式:
StartService:
-
开启一个后台服务
4.png
-
开启服务所执行的方法
5.png
-
关闭服务
6.png
- 关闭服务所执行的方法
-
连续两次点击开启服务
8.png
总结一下:其实通过稍微的测试就可以知道,在我们第一次点击开启服务的时候,系统会调用onCreate->onStartCommend->onStart方法,而在后续的操作过程中,服务只会调用onStartCommend->onStart方法,关闭服务就显得简单多了,直接会调用onDestroy方法。需要注意的是,Service同样需要在清单文件里面进行申明,如下所示:
9.png
其中,enabled表示该服务能否启动,exported表示该服务是否可以被外部调用。需要强调的一点就是,使用这种方式开启的服务不依托于启动类,换句话说,我们在activity里面启动Service之后,Service就和activity没有任何关系了,即使当前activity被销毁了,service依旧正常运行,只能通过stopService关闭服务。而且在这种方式下,activity与service不能直接交互。
BindService:
- 开启服务
注意看,bindService不像startService只传递一个服务的意图就可以了,它需要传递三个参数,那么这三个参数后面的两个参数代表什么意思呢?我们点进去源码看一下:
11.png
注意看,第二个参数需要传的是ServiceConnection类的实例,而第三个参数传的是一个标记位。ServiceConnection主要用于activity与service进行交互的辅助类,而第三个参数标志位传入BIND_AUTO_CREATE表示在活动和服务进行绑定后自动创建服务,这会使得Service中的onCreate方法得到执行,而onStartCommend方法不会执行。如下图所示:
12.png
那么,ServiceConnection到底干了些什么呢?其实也很简单
13.png
创建了一个ServiceConnection类,在里面复写它的两个方法,onServiceConnected方法代表服务连接,onServiceDisconnected代表服务关闭。现在我们调用unbindService(conn)看看调用方法
14.png关闭Service直接调用了onUnbind和onDestroy方法,那么在我们使用bindService的时候,Service又做了哪些操作呢?
首先,需要创建一个内部类继承自Binder
15.png然后在onBind方法中返回这个类的实例
16.png这样activity与service的连接就建立起来了,那么怎么交互呢?还是要回到
onServiceConnected(name: ComponentName?, service: IBinder?)
方法,注意看在这个方法里面第二个参数里面定义的是IBinder,而IBinder是一个接口,真正的实现是在Service里面,也就是我们自定义的类里面,所以我们可以在onServiceConnected方法里面做文章
17.png哈哈,看到没,简单的两行代码就拿到了MyService和MyService.MyBinder的实例,这个时候我们就完全可以在这里调用Service里面的方法啦。
与startService不同,bindService与宿主是有紧密联系的,所以为了防止内存泄漏,我们需要在onDestroy方法里面调用unbindService关闭Service。
到这里,关于Service的基本内容就结束了,下一篇我们继续深挖Service的其他内容。
网友评论