在安卓开发之Service学习过程中,遇到一个问题。多组件绑定服务,在执行解绑的过程中,最后一个组件解绑后,理应回调onUnbind()和onDestroy()方法。
但是实际操作的时候,却出了问题。最后一个组件解绑后,依旧无法回调onUnbind()和onDestroy()方法。
下面就这个问题的产生和解决方法进行叙述:
一、实验设计
1、实验目的:
为了验证多组件绑定同一个服务后,只有所有的组件都解除绑定 后才会调用onUnBind和onDestroy方法。
2、设计思路:
为了验证结论,需要至少两个组件来绑定服务,我们这里新建三个组件MainActivity,Activity1和Activity2,并且新建一个Service类MyService。
3、实现步骤:
(1)修改MainActivity和对应的布局文件,实现交互。 用户可通过点击按钮,绑定服务、调用服务中的方法、解绑服务和从该Activity跳转到另一个Activity;
(2)分别新建Activity1,Activity2和对应的布局文件,实现与MainActivity相同的功能;
(3)新建服务MyService继承Service类,并重写父类方法;
(4)运行程序,查看效果。
二、实验施行
1.1、修改MainActivity
1.2、修改与MainActivity对应的layout布局文件activity_main.xml
2、分别新建Activity1,Activity2和对应的布局文件(因功能与MainActivity相同,代码基本重复,就不再作截图演示)
下图为基本结构图:
3.1、新建服务MyService继承Service类,并重写父类方法。
通过这种方式,编译器会自动帮我们在 AndroidManifest.xml文件中注册,不需要自己添加,节省了时间。
3.2、新建服务MyService继承Service类,并重写父类方法。
三、运行程序,观察实验结果
如上图所示,此时已经将三个组件全部与Service服务所绑定了。接下来我们要做的就是逐个解绑,然后验证 最后一个组件解绑时会不会调用onUnbind和onDestroy方法。
从上图中我们可以看出,当最后一个组件解绑时,并没有回调onUnbind和onDestroy方法
四、问题分析
根据上课的时候单一组件解绑演示,我们可以知道,当唯一一个与服务绑定的组件解绑时是会回调onUnbind和onDestroy方法的。我们这里首先解绑了两个组件,逻辑上来讲,第三个组件解绑时,理应会回调上述两个方法的。
但是结果却和之前两个组件解绑的效果一样,于是联想到是不是还有组件没有解绑?但是只有三个组件,并且都已经解绑了。
忽然想到了activity的跳转,就猜想它跳转的时候是不是新建了一个activity活动。所以我们解绑的只是一个未绑定的组件?(这里并没有想到activity的四种启动模式)。
这时候还不确定,然后跑去看代码,看到这里的时候,发现只有一个if语句,只判断了该组件如果是绑定状态就解绑,却没有给出另一种判断结果的处理方式。
所以有了图中框起来的else语句。如果没有绑定,就提示用户先绑定。
再次运行,依旧是所有组件先绑定,然后再通过跳转依次解绑。然后就出现了下图的现象。
有了现象,那就证明猜想是正确的,即此时activity的跳转是新建了一个activity活动 然后就去查看之前任课老师刘老师给我们的课件PPT,找到了下面的一副图。(关于activity跳转的实例,一个普通的火车购票流程跳转)
是的,没错,在没有设置启动模式的时候,默认的启动模式是 standard模式,每次 启动,都会在栈顶新建一个activity。
知道问题在哪了,就好解决问题了!
五、解决方案
在AndroidManifest.xml文件中设置activity的启动模式为singleInstance,即如果一个activity活动被创建后,以后都不会再创建,需要的时候直接调用。
六、验证解决方案是否有效
再次运行,效果展示
好的,问题完美解决!
这次问题的产生主要是由于activity的启动模式导致的!
在没有设置启动模式的时候,默认的启动模式是 standard模式,每次跳转启动activity,都会在栈顶新建一个activity。导致不能回到之前绑定服务的activity活动。组件没有解绑服务,自然就不会回调onUnbind和onDestroy方法。
问题解决的方法就是将启动模式设置为singleInstance模式。如果你忘了activity的四种启动模式,请自行复习之前学习过的关于activity生命周期的知识点。
七、事后总结
如果认为掌握了平常课堂上演示的范例,那你就学会了课堂上所讲解的知识点。那就大错特错,真正的掌握不是说你能够复现别人的代码,而是要在吃透别人的代码之后,能够有自己的理解。能够自己去根据需求,从设计到实现,完全自己独立完成。这样才能说你学会了。学习不是僵硬的去模仿,不是看着其他人的程序,自己模仿着实现出来就自以为自己会了。如果相同的需求,换个环境后,你还是能独立实现,这才代表学会了。
写这些话,谨以自勉!