您现在的位置是:首页 > 文章详情

Receiver和Service是如何做到和Activity的生命周期绑定的?

日期:2018-05-10点击:532

在Activity中registeReceiver或者bindService,如果Activity销毁时还没进行unregisterReceiver或者unbindService,就会出现如下错误:

1、未调用unregisterReceiver:android.app.IntentReceiverLeaked: Activity xxxxx has leaked

2、未调用unbindService:android.app.ServiceConnectionLeaked: Activity xxxxx has leaked

出现这两个错误的原因是:Activity在退出后会调用onDestroy方法,然后会释放一些资源,流程如下:

img_537d0cc97fe442f70f6516455ece0e87.png
finishActivity流程图

最终运行LoadedApk.removeContextRegistrations,该方法就是用来实现Receiver和Service的泄漏处理。

img_7486f1da62d1bf484e2bd9f69ec2f36d.png
检测Activity的receiver释放leak

在Activity.finish后如果没有调用unregisterReceiver,就会出现泄漏。其中mReceivers是当前App注册的所有Receiver,在如果rmap不为空,且size大于0,说明Activity对应的Context中的Receiver还没有回收,Receiver会引用Activity,Activity就存在Leak。那么mReceiver中的值是哪里来的呢?答案就是regeisterReceiver函数,流程如下:

img_8945f7b1eb65caf1a5e9f12e83fa0d7a.png
register unregister流程

在注册广播的时候调用LoadedApk.getReceiverDispatcher会将BroadcastReceiver存储到mReceiver中,unRegisterReceiver会通过forgetReceiverDispatcher将BroadcastReceiver从mReceiver中移除,如果没有unRegisterReceiver,在退出Activity就会出现android.app.IntentReceiverLeaked: Activity xxxxx has leaked错误。

img_cb87585b50136304050c0398dc41fc14.png
检查Service是否泄漏

如果smap中Activity的Context对应的ServiceDispatcher不为空,说明Activity在调用bindService后没有主动调用unbindService,而ServiceConnectin会引用Activity,Activity就会存在Leak。流程和Receiver类似:

img_aac03ec6379e7e3d682895354fef1e66.png
bindService unbindService

bindService或调用LoadedApk.getServiceDispatcher将ServiceDispatcher加入mService中,unbindService通过forgetServiceDispatcher将ServiceDispatcher进行移除。如果不调用unbindService就会出现Activity Leak。

但是在APP运行的时候并没有出现Crash,是因为LoadedApk.removeContextRegistrations只是打印了泄漏信息,之后会再次调用AMS的unregisterReceiver或者unbindService。

因此,Receiver和bindService可以实现和Activity生命周期的联动。

原文链接:https://yq.aliyun.com/articles/638375
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章