有关Service的startService与bindService在各种情形下生命周期的变化
来源:互联网 发布:vb眼镜正品多少钱 编辑:程序博客网 时间:2024/05/20 05:27
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推出栈并回到桌面)
情景:
1、
先有一个Activity startService(跳转到后面当Activity时没有被销毁,只能被压到了栈底),之后有多个Activity bindService,然后跳转带最后一个Activity时,先bindService,然后直接stopService,之后再依次将Activity推出栈,从上面的运行截图可以看到,当Service被stopService,Service没有立即被销毁,然后一直等到了最初bindService的Activity被销毁之后(从日志可以看到先MainActivity被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)。
9、
10、
如果只是在第一个Activity中bindService,然后在把Activity推出栈,在Activity执行onDestory之后,Service才自动执行unbindService然后被销毁。
11、
根据上述的几个情景的验证,可以得出如下结论:
【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
。
- 有关Service的startService与bindService在各种情形下生命周期的变化
- startService与bindService混合使用对Service生命周期的影响
- startService与bindService混合使用对Service生命周期的影响
- startService与bindService混合使用对Service生命周期的影响
- android service startService与bindService的区别
- Service之startService,bindService交叉使用时的生命周期
- Android 面试题笔记-------bindservice与startservice的生命周期?
- android四大组件之一Service的startService()与bindService()区别?
- Service(二)startService与bindService的区别
- startService与bindService的区别
- startService与bindService的区别
- startService 与 bindService的区别
- startService与bindService的区别
- startService与bindService的区别
- startService与bindService的区别
- startService与bindService的区别
- startService与bindService的区别
- startService与bindService的区别
- 【连载】Floyd求最短路径算法设计 — Java版
- Netty——基本使用介绍
- 171116 逆向-初探PCQQ防撤回
- java网络编程之NIO(二)
- Codeforces 230E
- 有关Service的startService与bindService在各种情形下生命周期的变化
- IntelliJ IDEA 设置代码提示或自动补全的快捷键 (附IntelliJ IDEA常用快捷键)
- 小波变换教程(十四)
- Java反射机制与动态代理(一)
- 这些年MySQL表设计踩过的坑!
- shell批量互信脚本
- HTML——标签基础(单标签)
- Hibernate组件映射
- C语言实现单链表