美文网首页Android知识程序员Android开发经验谈
Receiver和Service是如何做到和Activity的生

Receiver和Service是如何做到和Activity的生

作者: JasmineBen | 来源:发表于2018-05-11 10:54 被阅读0次

    在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方法,然后会释放一些资源,流程如下:

    finishActivity流程图

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

    检测Activity的receiver释放leak

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

    register unregister流程

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

    检查Service是否泄漏

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

    bindService unbindService

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

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

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

    相关文章

      网友评论

        本文标题:Receiver和Service是如何做到和Activity的生

        本文链接:https://www.haomeiwen.com/subject/uclxdftx.html