Android Service、IntentService,Se
导读
- 移动开发知识体系总章(Java基础、Android、Flutter)
- Service是什么
- LocalService和RemoteService
- Service及其生命周期
- startService方式启动Service
- bindService 方式启动Service
- 多个组件绑定同一Service
- Service 与应用组件通信的几种方式
- IntentService
- Service在清单文件中的声明
- Service启动服务实现方式及其详解
- Service绑定服务的三种实现方式
- 关于启动服务与绑定服务间的转换问题
- 前台服务以及通知发送
- 服务Service与线程Thread的区别
- 管理服务生命周期的要点
- Android 5.0以上的隐式启动问题及其解决方案
- 保证服务不被杀死的实现思路
Service是什么
Service是Android中的四大组件之一,是实现程序后台运行的解决方案,Service非常适合是去执行那些不需要和用户交互而且还要长期运行的任务。即使程序被切换到后台,或者用户打开了另一个应用程序,服务仍然能够保持独立运行。不过需要注意的是,服务并不是运行在一个独立的进程当中,而是依赖于创建服务时所在的应用程序进程。当某个应用程序被杀掉时,所有依赖该进程的服务也会停止运行
LocalService和RemoteService
service基本上分为两种形式:
LocalService:本地服务,通常使用的Service默认依附在主进程上,生命周期跟随当前主进程(无手动stop的情况下)当主进程被Kill后,服务便会终止。
RemoteService:远程服务,指Service不依附于当前项目进程,而是对应项目所在包名加上指定的android:process字符串命名的进程,属于独立的进程,会占用一定资源,不受其他进程影响,需要通过使用AIDL进行IPC通信,使用比较麻烦。一般用于系统的Service,这种Service是常驻的。指的是服务和启动服务的activity不在同一个进程中。
注意(启动本地服务用的是显式启动; 远程服务的启动要用到隐式启动)
Service及其生命周期
Service也有自己的生命周期,在不同的时刻,系统会调用对应的Service生命周期函数,我们通过官方给出的一张图片来体会一下:
Service生命周期生命周期方法说明
onStartCommand()
当另一个组件(如 Activity)通过调用 startService() 请求启动服务时,系统将调用此方法。一旦执行此方法,服务即会启动并可在后台无限期运行。 如果您实现此方法,则在服务工作完成后,需要由您通过调用 stopSelf() 或 stopService() 来停止服务。(如果您只想提供绑定,则无需实现此方法。)
onBind()
当另一个组件想通过调用 bindService() 与服务绑定(例如执行 RPC)时,系统将调用此方法。在此方法的实现中,您必须通过返回 IBinder 提供一个接口,供客户端用来与服务进行通信。请务必实现此方法,但如果您并不希望允许绑定,则应返回 null。
onCreate()
首次创建服务时,系统将调用此方法来执行一次性设置程序(在调用 onStartCommand() 或 onBind() 之前)。如果服务已在运行,则不会调用此方法。
onDestroy()
当服务不再使用且将被销毁时,系统将调用此方法。服务应该实现此方法来清理所有资源,如线程、注册的侦听器、接收器等。 这是服务接收的最后一个调用。
Service 和Activity 一样同为Android 的四大组件之一,并且他们都有各自的生命周期,要想掌握Service 的用法,那就要了解Service 的生命周期有哪些方法,并且生命周期中各个方法回调的时机和作用。有一点比较重要,Service 有两种启动方式,并且它的两种启动方式的生命周期是不一样的。
注意事项
1、你应当知道在调用 bindService 绑定到Service的时候,你就应当保证在某处调用 unbindService 解除绑定(尽管 Activity 被 finish 的时候绑定会自 动解除,并且Service会自动停止);
2、你应当注意 使用 startService 启动服务之后,一定要使用 stopService停止服务,不管你是否使用bindService;
3、同时使用 startService 与 bindService 要注意到,Service 的终止,需要unbindService与stopService同时调用,才能终止 Service,不管 startService 与 bindService 的调用顺序,如果先调用 unbindService 此时服务不会自动终止,再调用 stopService 之后服务才会停止,如果先调用 stopService 此时服务也不会终止,而再调用 unbindService 或者 之前调用 bindService 的 Context 不存在了(如Activity 被 finish 的时候)之后服务才会自动停止;
4、当在旋转手机屏幕的时候,当手机屏幕在“横”“竖”变换时,此时如果你的 Activity 如果会自动旋转的话,旋转其实是 Activity 的重新创建,因此旋转之前的使用 bindService 建立的连接便会断开(Context 不存在了),对应服务的生命周期与上述相同。
5、在 sdk 2.0 及其以后的版本中,对应的 onStart 已经被否决变为了 onStartCommand,不过之前的 onStart 任然有效。这意味着,如果你开发的应用程序用的 sdk 为 2.0 及其以后的版本,那么你应当使用 onStartCommand 而不是 onStart。
startService方式启动Service
当应用组件通过startService方法来启动Service 时,Service 则会处于启动状态,一旦服务启动,它就会在后台无限期的运行,生命周期独立于启动它的组件,即使启动它的组件已经销毁了也不受任何影响,由于启动的服务长期运行在后台,这会大量消耗手机的电量,因此,我们应该在任务执行完成之后调用stopSelf()来停止服务,或者通过其他应用组件调用stopService 来停止服务。
Intent intent = new Intent(this,SimpleService.class);
startService(intent);
被启动的Service的生命周期:如果一个Service被某个Activity 调用 Context.startService 方法启动,那么不管是否有Activity使用bindService绑定或unbindService解除绑定到该Service,该Service都在后台运行。如果一个Service被startService 方法多次启动,那么onCreate方法只会调用一次,onStart将会被调用多次(对应调用startService的次数),并且系统只会创建Service的一个实例(因此你应该知道只需要一次stopService调用)。该Service将会一直在后台运行,而不管对应程序的Activity是否在运行,直到被调用stopService,或自身的stopSelf方法。当然如果系统资源不足,android系统也可能结束服务。
bindService 方式启动服务
除了startService 来启动服务之外,另外一种启动服务的方式就是通过bindService 方法了,也就是绑定服务,其实通过它的名字就容易理解,绑定即将启动组件和服务绑定在一起。前面讲的通过startService 方式启动的服务是与组件相独立的,即使启动服务的组件(Acitivy)被销毁了,服务仍然在后台运行不受干扰。但是通过bindSerivce 方式绑定的服务就不一样了,它与绑定组件的生命周期是有关的。如下:多个组件可以绑定到同一个服务上,如果只有一个组件绑定服务,当绑定的组件被销毁时,服务也就会停止了。如果是多个组件绑定到一个服务上,当绑定到该服务的所有组件都被销毁时,服务才会停止。
public class SimpleService extends Service {
public static final String TAG = "SimpleService";
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG,"call onBind...");
//返回IBinder 接口对象
return new MyBinder();
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG,"call onUnbind...");
return super.onUnbind(intent);
}
@Override
public void onCreate() {
Log.i(TAG,"call onCreate...");
}
@Override
public void onStart(Intent intent, int startId) {
Log.i(TAG,"call onStart...");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG,"call onStartCommand...");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.i(TAG,"call onDestroy...");
}
// 添加一个类继承Binder
public class MyBinder extends Binder{
// 添加要与外界交互的方法
public String getStringInfo(){
return "调用了服务中的方法";
}
}
}
多个组件绑定同一服务
Service 与应用组件通信的几种方式
- BroadcastReceiver
- LocalService 使用Binder 和 服务通信
IntentService
IntentService 是Service 的子类,它使用工作线程逐一处理所有启动请求,果您不要求服务同时处理多个请求,这是最好的选择。 您只需实现 onHandIntent方法即可,该方法会接收每个启动请求的 Intent,使您能够执行后台工作。
参考文献
Service生命周期
Android Service、IntentService,Service和组件间通信