Service:
- Service是一个应用组件,后台操作运行,不需要用户界面;
- Service不是进程也不是线程
- 两种形式:Started and Bound
关于manifest定义Service里面的参数:
- name
- label
- icon
- enable:是否被系统默认调用
- exported:是否允许其他应用可以使用该服务
主要重构方法
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
Bind:绑定
生命周期
注:onStart()已被onStartCommand()替换。
两种启动服务方式:
- 第一种:
startService(intent);
stopService(intent);
- 第二种:
bindService(intent, serviceConnection, BIND_AUTO_CREATE);
unbindService(serviceConnection);
理解: 两种方法都是启动Service,bindService的方法能使Service与界面交互,传输数据。
问题:如何传输数据呢?
大概思路:
首先绑定数据时bindService(intent, serviceConnection, BIND_AUTO_CREATE); 将携带serviceConnection 到指定的service;
然后Service里面有个“public IBinder onBind(Intent intent) ”的方法,onCreate()之后会调用这方法,这方法会返回一个IBinder(什么是IBinder?首先要明白,Android的远程调用(就是跨进程调用)就是通过IBinder实现的;要实现IBinder来支持远程调用,应从Binder类派生一个类。)
这个return就会返回到之前的serviceConnection ,serviceConnection 有一个onServiceConnected(ComponentName name, IBinder service)的重构方法,看下图,localBinder就是上图创建的一个类。个人认为这个类似findViewById()的作用。
获取了Service后就可以调用Service里面自定义的get方法获取所需数据。例如
总结,serviceConnection 就是一个桥梁、一个通道,而IBander是一个装载货物在通道里行走的。
网上搜了下,关于service的两种开启方式:
- 通过startservice开启的服务.一旦服务开启, 这个服务和开启他的调用者之间就没有任何的关系了. 调用者不可以访问 service里面的方法. 调用者如果被系统回收了或者调用了ondestroy方法, service还会继续存在
- 通过bindService开启的服务,服务开启之后,调用者和服务之间 还存在着联系 , 一旦调用者挂掉了.service也会跟着挂掉 .
关于生命周期
网上摘抄的,感觉有用
1). 被启动的服务的生命周期:如果一个Service被某个Activity 调用 Context.startService 方法启动,那么不管是否有Activity使用bindService绑定或unbindService解除绑定到该Service,该Service都在后台运行。如果一个Service被startService 方法多次启动,那么onCreate方法只会调用一次,onStart将会被调用多次(对应调用startService的次数),并且系统只会创建Service的一个实例(因此你应该知道只需要一次stopService调用)。该Service将会一直在后台运行,而不管对应程序的Activity是否在运行,直到被调用stopService,或自身的stopSelf方法。当然如果系统资源不足,android系统也可能结束服务。
2). 被绑定的服务的生命周期:如果一个Service被某个Activity 调用 Context.bindService 方法绑定启动,不管调用 bindService 调用几次,onCreate方法都只会调用一次,同时onStart方法始终不会被调用。当连接建立之后,Service将会一直运行,除非调用Context.unbindService 断开连接或者之前调用bindService 的 Context 不存在了(如Activity被finish的时候),系统将会自动停止Service,对应onDestroy将被调用。
3). 被启动又被绑定的服务的生命周期:如果一个Service又被启动又被绑定,则该Service将会一直在后台运行。并且不管如何调用,onCreate始终只会调用一次,对应startService调用多少次,Service的onStart便会调用多少次。调用unbindService将不会停止Service,而必须调用 stopService 或 Service的 stopSelf 来停止服务。
4). 当服务被停止时清除服务:当一个Service被终止(1、调用stopService;2、调用stopSelf;3、不再有绑定的连接(没有被启动))时,onDestroy方法将会被调用,在这里你应当做一些清除工作,如停止在Service中创建并运行的线程。
关于onStartCommand() 返回值:
- START_NOT_STICKY:当Service因为内存不足而被系统kill后,接下来未来的某个时间内,即使系统内存足够可用,系统也不会尝试重新创建此Service。除非程序中Client明确再次调用startService(...)启动此Service。
- START_STICKY:当Service因为内存不足而被系统kill后,接下来未来的某个时间内,当系统内存足够可用的情况下,系统将会尝试重新创建此Service,一旦创建成功后将回调onStartCommand(...)方法,但其中的Intent将是null,pendingintent除外。
- START_REDELIVER_INTENT:与START_STICKY唯一不同的是,回调onStartCommand(...)方法时,其中的Intent将是非空,将是最后一次调用startService(...)中的intent。