Activity模版:
public class MainActivity extends AppCompatActivity{
private ServiceConnection connection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
log("onServiceConnected");
}
@Override
public void onServiceDisconnected(ComponentName name) {
log("onServiceDisconnected");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
log("onCreate");
}
public void click1(View view) {
int id = view.getId();
switch (id) {
case R.id.bt_1_1:
log("click -> startService");
startService(new Intent(this,MyService.class));
break;
case R.id.bt_1_2:
log("click -> stopService");
stopService(new Intent(this,MyService.class));
break;
case R.id.bt_1_3:
log("click -> bindService");
bindService(new Intent(this,MyService.class),connection,BIND_AUTO_CREATE);
break;
case R.id.bt_1_4:
log("click -> unbindService");
unbindService(connection);
break;
case R.id.bt_1_5:
log("click -> to next activity");
startActivity(new Intent(this,Main2Activity.class));
break;
default:
}
}
@Override
protected void onDestroy() {
super.onDestroy();
log("onDestroy");
}
private void log(String msg) {
Log.d("TAG-MainActivity", msg);
}
}
Service设置:
public class MyService extends Service {
private MyBinder binder = new MyBinder();
@Override
public void onCreate() {
super.onCreate();
log("onCreate");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
log("onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
log("onBind");
return binder;
}
@Override
public boolean onUnbind(Intent intent) {
log("onUnbind");
return super.onUnbind(intent);
}
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
log("bindService");
return super.bindService(service, conn, flags);
}
@Override
public void unbindService(ServiceConnection conn) {
super.unbindService(conn);
log("unbindService");
}
@Override
public void onDestroy() {
super.onDestroy();
log("onDestroy");
}
@Override
public boolean stopService(Intent name) {
log("onDestroy");
return super.stopService(name);
}
private void log(String msg) {
Log.d("TAG-MyService", msg);
}
static class MyBinder extends Binder {
}
}
说明:有三个Activity,分别为MainActivity、Main2Activity、Main3Activity,这三个Activity 的实现完全复制于上述模版,只不过Main3Activity中跳转到下一个Activity的点击事件实际的实现。
####接下来,将会对各种情景进行实践,观察Service的生命周期变化。
(说明:红色框代表第一个Activity,即MainActivity,黄色的代表Main2Activity,蓝色代表Main3Activity,箭头向下表示从当前Activity跳转到下一个Activity,箭头向上则表示把当前Activity 推出栈回到上一个Activity,框内的表示当前Activity对同一个Service的操作,空白表示不做任何操作。当然最后都会把第一个Activity推出栈并回到桌面)
#情景:
先有一个Activity startService(跳转到后面当Activity时没有被销毁,只能被压到了栈底),之后有多个Activity bindService,然后跳转带最后一个Activity时,先bindService,然后直接stopService,之后再依次将Activity推出栈,从上面的运行截图可以看到,当Service被stopService,Service没有立即被销毁,然后一直等到了最初bindService的Activity被销毁之后(从日志可以看到先Main2Activity被onDestory然后才是Service被onDestory),Service才被销毁,此时也没有对startService的Activity做任何操作。
###2、
这次是在第一个Activity中bindService,在第二个中startService,再最后一个中bindService,然后回退Activity的时候在最后一个中unbindService,第二个不错操作,回到第一个unbindService,最后把第一个也推出栈,然后从运行日志中可以看到,在最后Service没有执行onDestory方法,也就是表明Service还存在,没有被销毁,这一点从日志画红圈的部分(重新进入第一个Activity并startService)也可以得以验证。
###3、
这一次只是单单在两个Activity中执行bindService以及unbindService操作,可以看到,此时在第一个Activity销毁前,Service已经在执行了unbindService操作后被销毁了,与(1)存在些许区别。
###4、
在这次的尝试中,从输出的日志可以看到,当在第二个Activity中stopService之后,Service没有被立即销毁,而是一直等到第一个Activity被onDestory之后(也就是最后一个与其绑定的Context销毁之后),它才自动被销毁,情况和(1)类似。
###5、
在这一次的尝试中,可以看到,最后在第一个Activity中执行完unbindService之后,Service正常的被销毁。
###6、
根据运行流程与输出的日志可以看到,虽然在第二个Activity中没有unbindService,但是当第二个Activity onDestory之后,其绑定到Service中的Context也就失效了,然后回到第一个Activity中执行unbindService之后,Service就立即被销毁了。
###7、
这次在第一个Activity中unbindService之后,Service也被正常销毁了。
###8、
这次,在第二个Activity中startService后没有进行stopService,在第三个Activity中bindService后也没有unbindService,只有在第一个Activity推出栈之前执行unbindService,从运行日志可以看出,Service没有被销毁,还处于运行状态(从画圈部分的日志可以得以验证,再次进入程序,在第一个Activity中startService并没有执行onCreate只执行了onStartCommand)。
###10、
如果只是在第一个Activity中bindService,然后在把Activity推出栈,在Activity执行onDestory之后,Service才自动执行unbindService然后被销毁。
###根据上述的几个情景的验证,可以得出如下结论:
【1】当startService单独使用时,即使对应的startService
时传入的Context被销毁,Service也还是会处于运行状态。
【2】无论多少个Activity绑定了Service,但是onBind()
只会执行一次,也就是Service首次被绑定时会执行,onUnbind()
也是如此,即最后一个Context失效后,才会执行onUnbind()
(Activity主动调用unbindService
或者被onDestory
)。
**而如果由于Activity没有主动调用unbindService与Serivice解绑,这样会造成内存泄漏。**如截图:
(这里需要说明的是,只要Activity在bindService后,如果在销毁前没有主动调用unbindService,就会引发内存泄漏。)
而最后一个Context
的意思是所有Context中最后一个失效的Context,假设有两个Activity,都绑定了Service,且在从第一个Activity跳转带第二个Activity,当在第二个Activity中bindService
后,借助广播或者其他途径直接finish掉第一个Activity(可以在第一个Activity被销毁前先unbindService
),这样,在第二个Activity与Service绑定时传入的Context就成了最后一个Context了。
【3】当只有一个Activity与Service进行bindService而没有startService,则Activity在onDestory
前如果没有主动调用unbindService
与Service解除绑定,或者只是直接调用stopService
,则需要等到Activity被销毁,也就是与Service绑定的Context失效时,Service才会执行onUnbind()
,之后会自动调用onDestory()
进行销毁。
【4】
如果是多个Activity都绑定了同一个Service绑定,且没有执行过startService,当其中一个Activity onDestory
或者进行unbindService
之后,其与Service进行bindService
时的Context就会失效,而当最后与Service绑定的Contxet失效后,Service才会执行onUnbind()
,之后会自动调用onDestory()
进行销毁。
【5】
如果是同时有多个Activity对Service进行了startService
和bindService
,如果没有显示调用过stopService
,则当所有与Service绑定的Context失效后,Service不会被销毁,会一直在后台运行,因为有主动调用了startService
,此时必须主动调用stopService
或者在Service中调用stopSelf才能将其销毁;而如果在一个或者多个Context失效前主动调用了stopService
或者在Service中调用stopSelf
,则需要等到最后一个Context主动与Service进行unbindService
或者失效后,才会能使Service执行onDestory
。