2.后台服务
后台服务就是处于后台运行的
生命周期:
图:左图:启动方式的生命周期 右图:绑定方式的生命周期
注意:本地服务中,onStart已经被onStartCommand方法取代,Service和Activity都是由Context类派生的,可以通过getApplicationContext()方法获取上下文对象,和Activity一样,它有着自己的生命周期,可是和Activity相比,它所执行的过程略有不同,如上图所示。
在服务分类中,提到了3种服务通信类型,一种是通过startService()直接启动服务,一种是通过bindService()的方式启动,2种启动方式对应的生命周期如上图所示。3.使用AIDL方式的Service
下面就说说2种服务的启动流程:
1.context.startService() 启动流程(后台处理工作):
context.startService() -> onCreate() -> onStartCommand() -> Service running -> context.stopService() -> onDestroy() -> Service stop
所以调用startService的生命周期大致为:
onCreate(只在创建的时候调用一次直到被摧毁) --> onStartCommand (服务开启后,可多次调用) --> onDestroy
服务中的onStartCommand(Intent intent, int flags, int startId)方法会返回一个唯一的整数标识符来识别启动请求,启动请求可以是START_STICKY、START_STICKY_COMPATIBILITY、START_NOT_STICKY、START_REDELIVER_INTENT等,标志位可以是START_FLAG_REDELIVERY、START_FLAG_RETRY。
通过这种方式,服务并不会随着绑定组建的摧毁而摧毁,而是服务自我摧毁。(所以这种方式适用于文件下载,上传等请求自行运行的场景)。
从图中我们可以看出,onCreate方法只在创建时候被调用了一次,这说明:Service被启动时只调用一次onCreate()方法,如果服务已经被启动,在次启动的Service组件将直接调用onStartCommand()方法,通过这样的生命周期,可以根据自身需求将指定操作分配进onCreate()方法或onStartCommand()方法中。
2.context.bindService()启动流程(在本地同一进程内与Activity交互):
context.bindService() -> onCreate() -> onBind() -> Service running -> onUnbind() -> onDestroy() -> Service stop
bindService的生命周期简化为为:onCreate --> onBind --> onUnbind --> onDestory。
通过该方法,服务启动时会调用onCreate()来启动服务,可是它不会调用onStartCommand() 方法,并且只有在所有的服务都接触了后,服务才会自动停止运行。通过服务的onBind()方法,可以获的一个客户端与服务器进行通信的IBdiner接口。IBind允许客户端回调服务的方法,比如得到Service的实例、运行状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind->onDestroy相应退出。
注:绑定服务的Android组建在摧毁前应解除绑定,否则会造成内存泄漏。
3.使用AIDL方式的Service(进行跨进程通信)(这块不是很懂,这里就不提了)
使用方式
1.创建服务类
public class MyService extends Service {}
2.在AndroidMainfest.xml文件中配置注册该Service
3. 启动服务
(1)通过直接启动服务的方式:
Intent intent = new Intent(getApplicationContext(), MyService.class);
startService(intent);
服务类中:
@Override
public void onCreate() {
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//接受传递过来的intent的数据等
return START_STICKY;
}
@Override
public void onDestroy() {
}
(2)通过绑定启动服务的方式:
绑定一个服务,需要设置ServiceConnection和标志位,方法如下:
bindService(Intent service, ServiceConnection conn, int flags)
ServiceConnection可以监听服务的状态,在进行服务绑定的时,其标志位可以为以下几种(这里列出3种):
1).Context.BIND_AUTO_CREATE
说明:表示收到绑定请求的时候,如果服务尚未创建,则即刻创建,在系统内存不足需要先摧毁优先级组件来释放内存,且只有驻留该服务的进程成为被摧毁对象时,服务才被摧毁
2).Context.BIND_DEBUG_UNBIND
说明:通常用于调试场景中判断绑定的服务是否正确,但容易引起内存泄漏,因此非调试目的的时候不建议使用
3).Context.BIND_NOT_FOREGROUND
说明:表示系统将阻止驻留该服务的进程具有前台优先级,仅在后台运行,该标志位位于Froyo中引入。
注意:绑定服务的以异步方式运行的。绑定服务必须在当前的上下文环境中运行,某些场景中,通过上下文进行添加绑定接触方法如下:
getApplicationContext().bindService(service, conn, flags)
代码如下:
/** 是否绑定 */
boolean mIsBound = false;
/** 绑定服务 */
public void doBindService() {
bindService(new Intent(MainActivity.this, LocalService.class), mConnection,Context.BIND_AUTO_CREATE);
mIsBound = true;
}
/** 解除绑定服务 */
public void doUnbindService() {
if (mIsBound) {
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mBoundService = ((LocalService.LocalBinder) service).getService();
Toast.makeText(MainActivity.this, 服务连接, Toast.LENGTH_SHORT)
.show();
}
@Override
public void onServiceDisconnected(ComponentName name) {
mBoundService = null;
Toast.makeText(MainActivity.this, 服务未连接, Toast.LENGTH_SHORT)
.show();
}
};
服务类中:
@Override
public void onCreate() {
}
/** 绑定的IBinder */
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
public LocalService getService() {
return LocalService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
return super.onUnbind(intent);
}
4.停止服务
(1)启动服务停止有2种方法:
1)stopSelf() 自我停止服务
2)stopService(Intent name) 被动停止服务
(2)绑定服务的解除绑定方法如下:
unbindService(ServiceConnection conn)