Service作为android的四大组件之一,其在manifest中的配置、两种启动方式和生命周期相信大家都已熟知,本篇文章的重点不在这里,基本技术点只做简单讲述,本文的重点是介绍一下本地service和远程服务、AIDL、service与activity的区别、service和Thread或者Process的关系。
先说一下基本知识点:大家都知道要想启动一个service,首先要在manifest中定义你的service,然后再在其它组件中启动,启动方式有两种,一种是startService,一种是bindService:
startService的生命周期是onCerate,onstartCommand,ondestroy,其中onCreate只执行一次,onstartCommand可以执行多次,结束这个service有两种方式,一种调用stopService,一种stopSelf。
bindService的生命周期是onCreate,onbind,onunbind,ondestroy,结束这个service调用unbindService,其中要注意的是oncreate和onbind只调用一次,比如你在同一个activity中一直调用bindService,第一次的时候依次调用了onCerate,onbind,onServiceConnected,第二次在调用bindService就没任何反应了,这时候你启动另一个activity再次调用bindService,你会发现也只会回调了onSercieConnected方法,onSercieConnected方法是在ServiceConnection中的方法,相信大家也比较熟悉。
OK,基本东西先说这些。
接下来先说一下本地服务和远程服务:首先何为本地服务:我们首先要想到的是要在我们自己程序的内部进行的一些任务操作,然后远程服务是调用别的App中的暴漏出来的接口。那我们通常用到的比较多的就是本地服务,比如升级操作,时时定位操作,播放音乐操作等等。对于远程服务,大家接触的稍微少一点,因为这涉及到进程间的通信(RPC),这时候要想实现进程间的通信,就需要使用android interface define language,俗称android接口定义语言(AIDL),对于AIDL的使用呢其实和bindService时自定义一个Bind类的使用方式差不多,这里需要注意的是如果你使用的是Eclipse这个IDE,你生成一个aidl文件之后gen目录下自动生成一个对应名字的java文件,而如果你使用AS的话,生成一个aidl文件之后需要build project一下,然后才有对应的java文件。然后你怎么才能在自己的app中调用人家的接口呢,首先你要把人家的aidl文件copy过来,包括完整的包名,然后呢隐式启动人家的service就可以了。还有一点,在我们使用第三方推送的时候,拿小米推送来说:
<service
android:name="com.xiaomi.push.service.XMPushService"
android:enabled="true"
android:process=":pushservice" />
大家看最后一行,这是什么意思呢,如果我们自己写一个service,然后加上process属性会怎么样呢,首先你要明白这是定义了一个process(进程),大家都知道一个App就一个进程,那如果这样写的话就开启了另一个进程。我们可以自己写一个Service,然后在manifest中加上
android:process=":XXX"
然后在自己的service中写入Thread.sleep(5000),发现没有发生ANR现象,这是因为它们就不在一个进程中,不存在阻塞显现。
然后说一下service和activity、thread、process:大家都知道activity有界面,service没有UI显示,然后service也运行在UI线程中,那为什么还有使用service呢,service能做的事情activity都是可以完成的,:
首先如果我们定义了一个service,那任何一个activity都可以启动这个service,然后做操作,比如播放音乐,你不管从哪个activity跳转到另一个activity,你都可以优雅的控制音乐的播放、暂停等等。
虽然service默认是运行在UI线程的,但我们可以new 一个thread然后进行耗时操作,我们甚至可以在另一个进程中操作这个service,这个就显得安全。
系统可以重新启动异常死去的service,具体表现在onstartcommand函数:
public int onStartCommand(Intent intent, int flags, int startId) {},大家看一下该函数的返回值,int类型,什么意思呢,有三个返回值:
START_STICKY(常量值:1):sticky的意思是“粘性的”。使用这个返回值时,我们启动的服务跟应用程序"粘"在一起,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务。当再次启动服务时,传入的第一个参数将为null; START_NOT_STICKY(常量值:2):“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。 START_REDELIVER_INTENT(常量值:3):重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
5. service可以依赖bind机制,不需要在activity中处理负载的线程操作。
好了,service就分析到这里。