您的位置:首页 > 其它

四大组件之Service(二)-Service在各种情况下的生命周期

2016-06-13 13:38 281 查看

第3节 Service的生命周期

3.1 Service的生命状态

Activity
类似,
Service
也是有生命周期的。在实现一个
Service
的时候,可以覆盖它的生命周期函数,当它进入不同生命状态的时候,这些函数会被触发,我们就可以在它不同的生命阶段做不同的逻辑操作。

public class MyService extends Service {
public MyService() {
}

@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}

@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
}

@Override
public void onCreate() {
super.onCreate();
}

@Override
public void onDestroy() {
super.onDestroy();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
}


因为
Service
不像
Activity
有需要显示的界面,所以它的状态少了很多,没有
onResume()
onPause()
等等与界面显示相关的状态。

这里面的
onStartCommand()
函数与
onUnbind()
函数要特别注意,它们的返回值有特别的意义,会影响到
Service
的生命周期,我们会在最后单独解释。

3.2 生命周期

通过
startService()
运行的
Service
与通过
bindService()
运行的
Service
相比较,它们的生命周期有所不同。

假设
Service
-MyService 还没有被启动过,我们来看看它被一个或多个组件使用
startService()
stopService()
bindService()
unbindService()
这些方法后,生命周期会怎么变化。

组件名称启动Service的方法关闭Service的方法
AstartService()stopService()
BstartService()stopService()
CbindService()unbindService()
DbindService()unbindService()

3.2.1 Start Service的生命周期

对于只使用
startService()
stopService()
来控制
Service
的情况:

情况1

A -- startService() ->
MyService -- onCreate() ->
MyService -- onStartCommand() ->

A -- stopService() ->
MyService -- onDestroy()


情况2

A -- startService() ->
MyService -- onCreate() ->
MyService -- onStartCommand() ->

A -- startService() ->
MyService -- onStartCommand() ->

A -- stopService() ->
MyService -- onDestroy()


情况3

A -- startService() ->
MyService -- onCreate() ->
MyService -- onStartCommand() ->

B -- startService() ->
MyService -- onStartCommand() ->

A -- stopService() ->
MyService -- onDestroy()


情况4

A -- startService() ->
MyService -- onCreate() ->
MyService -- onStartCommand() ->

B -- startService() ->
MyService -- onStartCommand() ->

B -- stopService() ->
MyService -- onDestroy()


可以看出,

任意组件调用
startService()
后,如果这个
Service
还没有创建,系统会首先创建-
onCreate()


之后触发
onStartCommand()


任意组件调用
stopService()
后,如果这个
Service
还没有被销毁,系统会销毁-
onDestroy()


3.2.2 Bind Service的生命周期

onStartCommand()
函数与
onUnbind()
函数也会对生命周期有影响,所以这里我们假设使用的是默认的返回值,

@Override
public boolean onUnbind(Intent intent) {
//实际上是返回false
return super.onUnbind(intent);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//实际上是返回START_STICKY
return super.onStartCommand(intent, flags, startId);
}


组件触发
Service
运行的
startService()
函数也会对生命周期有影响--第三个参数,所以这里我们假设使用
Context.BIND_AUTO_CREATE


bindService(i, mServiceConnection, Context.BIND_AUTO_CREATE);


那么,对于只使用
bindService()
unbindService()
来控制
Service
的情况:

情况1

C -- bindService() ->
MyService -- onCreate() ->
MyService -- onBind() ->
C -- onServiceConnected()被触发 ->

C -- unbindService() ->
MyService -- onUnbind()
MyService -- onDestroy()


情况2

C -- bindService() ->
MyService -- onCreate() ->
MyService -- onBind() ->
C -- onServiceConnected()被触发 ->

C -- bindService() ->
MyService -- 无变化

C -- unbindService() ->
MyService -- onUnbind()
MyService -- onDestroy()


情况3

C -- bindService() ->
MyService -- onCreate() ->
MyService -- onBind() ->
C -- onServiceConnected()被触发 ->

D -- bindService() ->
MyService -- onBind() ->
D -- onServiceConnected()被触发 ->

C -- unbindService() ->
MyService -- onUnbind()

D -- unbindService() ->
MyService -- onUnbind()
MyService -- onDestroy()


情况4

C -- bindService() ->
MyService -- onCreate() ->
MyService -- onBind() ->
C -- onServiceConnected()`被触发 ->

D -- bindService() ->
MyService -- onBind() ->
D -- onServiceConnected()被触发 ->

D -- unbindService() ->
MyService -- onUnbind()

C -- unbindService() ->
MyService -- onUnbind()
MyService -- onDestroy()


可以看出,

任意组件调用
bindService()
后,如果这个
Service
还没有创建,系统会首先创建-
onCreate()


之后触发
onBind()


之后组件的
onServiceConnected()
被触发,告知绑定成功;

任意已绑定的组件调用
unbindService()
后,会触发
onUnbind()


如果这个
Service
没有与其他的组件绑定,那么系统会销毁-
onDestroy()


3.2.3 混合模式下的生命周期

对于使用了
startService()
stopService()
bindService()
unbindService()
等两种方式来控制
Service
的情况:

情况1

A -- startService() ->
MyService -- onCreate() ->
MyService -- onStartCommand() ->

C -- bindService() ->
MyService -- onBind() ->
C -- onServiceConnected()被触发 ->

C -- unbindService() ->
MyService -- onUnbind()

A -- stopService() ->
MyService -- onDestroy()


情况2

A -- startService() ->
MyService -- onCreate() ->
MyService -- onStartCommand() ->

C -- bindService() ->
MyService -- onBind() ->
C -- onServiceConnected()被触发 ->

A -- stopService() ->
MyService -- 无变化

C -- unbindService() ->
MyService -- onUnbind()
MyService -- onDestroy()


情况3

C -- bindService() ->
MyService -- onCreate() ->
MyService -- onBind() ->
C -- onServiceConnected()被触发 ->

A -- startService() ->
MyService -- onStartCommand() ->

C -- unbindService() ->
MyService -- onUnbind()

A -- stopService() ->
MyService -- onDestroy()


情况4

C -- bindService() ->
MyService -- onCreate() ->
MyService -- onBind() ->
C -- onServiceConnected()被触发 ->

A -- startService() ->
MyService -- onStartCommand() ->

A -- stopService() ->
MyService -- 无变化

C -- unbindService() ->
MyService -- onUnbind()
MyService -- onDestroy()


可以看出,

当一个
Service
被创建-
onCreate()
之后;如果任意组件想要销毁-
onDestroy()
这个
Service
;必须等到
Service
与它关联的所有组件切断联系(通过
stopService()
或者
unbindService()
)才行。

3.3 其它因素对生命周期的影响

Service
生命周期的影响还有其它的因素。

3.3.1 unbind()函数返回值

自定义
Service
时,
unbind()
函数的返回值对
Service
的生命周期是有影响的。它会决定
onRebind()
函数是否被调用。

前面我们都看到了在
unbind()
返回
false
Service
生命周期的变化。在
unbind()
返回
true
时,它的周期变化如下,

A -- startService() ->
MyService -- onCreate() ->
MyService -- onStartCommand() ->

C -- bindService() ->
MyService -- onBind() ->
C -- onServiceConnected()被触发 ->

C -- unbindService() ->
MyService -- onUnbind()

C -- bindService() ->
MyService -- onRebind() ->
C -- onServiceConnected()被触发 ->
......


也就是说,假如一个
Service
正在运行,此时有个组件C要绑定它,那么会触发
onBind()
函数;如果C解除绑定,然后又再次绑定,那么不会触发
onBind()
而是触发
onRebind()
函数。

3.3.2 bindService函数的参数

在绑定
Service
的时候,通常使用的
Context.BIND_AUTO_CREATE
参数,

bindService(i, mServiceConnection, Context.BIND_AUTO_CREATE);


如果不使用
Context.BIND_AUTO_CREATE
,那么一个
Service
在没有被运行起来之前,使用
bindService()
是不会让
Service
自动运行起来的。

但是如果设置上了这个参数,那么就会让它运行起来,然后进行绑定。

除了
Context.BIND_AUTO_CREATE
参数,还有好些参数可以使用,

BIND_NOT_FOREGROUND,
BIND_ABOVE_CLIENT,
BIND_ALLOW_OOM_MANAGEMENT,
BIND_WAIVE_PRIORITY,
BIND_IMPORTANT,
BIND_ADJUST_WITH_ACTIVITY


可以用
的方式同时使用其它的标志,例如,

bindService(i, mServiceConnection, Context.BIND_AUTO_CREATE|Context.BIND_NOT_FOREGROUND);


3.3.3 onStartCommand函数返回值

前面的
onStartCommand()
返回值使用的是
START_STICKY
,它对
Service
onStartCommand()
和周期都是有影响的。

Service
启动之后,如果因为某种意外而停止运行(例如代码写的不好,
Service
直接崩溃了),那么系统要自动的把这个
Service
再运行起来。这个时候,
onStartCommand()
的返回值就决定了
Service
重启的行为,

START_STICKY
Service
重启(onCreate())之后,会触发
onStartCommand()
,但是此时
onStartCommand()
的参数
Intent
会变成空值,

public class MyService extends Service {
public MyService() {
}

......

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent == null) {
//因为这个Service在onStartCommand()返回的是START_STICKY,所以异常退出后,传入的`intent`是空值
}
return START_STICKY;
}
}


START_NOT_STICKY
Service
将不会被自动重启,所以也就不会触发
onStartCommand()


START_REDELIVER_INTENT
Service
重启(onCreate())之后,会触发
onStartCommand()
,此时
onStartCommand()
的参数
Intent
不会变成空值。该
Intent
将是以前想要启动这个
Service
Intent
;如果以前有多个
Intent
想要启动它,那么这里会传入最后一个,也就是最近的一个;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: