Activity中bindService和registerReceiver的清理工作[通俗易懂]

Activity中bindService和registerReceiver的清理工作[通俗易懂]在Android开发中,我们经常需要注册BroadcastReceiver和bindservice。接口函数如下:publicIntentregisterReceiver(BroadcastReceiverreceiver,IntentFilterfilter);publicvoidunregisterReceiver(BroadcastReceiverrecei

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

在Android开发中,我们经常需要注册BroadcastReceiver和bind service。

接口函数如下:

public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter);

public void unregisterReceiver(BroadcastReceiver receiver);

public boolean bindService(Intent service, ServiceConnection conn, int flags);

public void unbindService(ServiceConnection conn);


有的时候,用户只调用了注册函数,或者是bind service,而忘记了unregisterReceiver和unbindService。这时,在Activity退出的时候,会自动这些问题,自动调用unregisterReceiver和unbindService。具体的流程如下:

    private void handleDestroyActivity(IBinder token, boolean finishing,
            int configChanges, boolean getNonConfigInstance) {

        ActivityClientRecord r = performDestroyActivity(token, finishing,
                configChanges, getNonConfigInstance);        回调Activity的onDestroy
        if (r != null) {

            // Mocked out contexts won’t be participating in the normal
            // process lifecycle, but if we’re running with a proper
            // ApplicationContext we need to have it tear down things
            // cleanly.
            Context c = r.activity.getBaseContext();
            if (c instanceof ContextImpl) {

                ((ContextImpl) c).scheduleFinalCleanup(
                        r.activity.getClass().getName(), “Activity”);     清理 注册的receiver和bind的service
            }
        }
        if (finishing) {

            try {

                ActivityManagerNative.getDefault().activityDestroyed(token);      通知AMS,activity已经destroy
            } catch (RemoteException ex) {

                // If the system process has died, it’s game over for everyone.
            }
        }
        mSomeActivitiesChanged = true;
    }

In ContextImpl.java

    final void scheduleFinalCleanup(String who, String what) {

        mMainThread.scheduleContextCleanup(this, who, what);
    }

In ActivityThread.java

    final void scheduleContextCleanup(ContextImpl context, String who,
            String what) {

        ContextCleanupInfo cci = new ContextCleanupInfo();
        cci.context = context;
        cci.who = who;
        cci.what = what;
        sendMessage(H.CLEAN_UP_CONTEXT, cci);
    }

                case CLEAN_UP_CONTEXT:
                    ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
                    cci.context.performFinalCleanup(cci.who, cci.what);
                    break;


In ContextImpl.java

    final void performFinalCleanup(String who, String what) {

        //Log.i(TAG, “Cleanup up context: ” + this);
        mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
    }

In LoadedApk.java

    public void removeContextRegistrations(Context context,
            String who, String what) {

        final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled();
        ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap =  mReceivers.remove(context);
        if (rmap != null) {

            for (int i=0; i<rmap.size(); i++) {      清理所有已经注册的receiver
                LoadedApk.ReceiverDispatcher rd = rmap.valueAt(i);
                IntentReceiverLeaked leak = new IntentReceiverLeaked(
                        what + ” ” + who + ” has leaked IntentReceiver “
                        + rd.getIntentReceiver() + ” that was ” +
                        “originally registered here. Are you missing a ” +
                        “call to unregisterReceiver()?”);
                leak.setStackTrace(rd.getLocation().getStackTrace());
                Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
                if (reportRegistrationLeaks) {

                    StrictMode.onIntentReceiverLeaked(leak);
                }
                try {

                    ActivityManagerNative.getDefault().unregisterReceiver(
                            rd.getIIntentReceiver());
                } catch (RemoteException e) {

                    // system crashed, nothing we can do
                }
            }
        }
        mUnregisteredReceivers.remove(context);
        //Slog.i(TAG, “Receiver registrations: ” + mReceivers);

        ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap =
            mServices.remove(context);
        if (smap != null) {

            for (int i=0; i<smap.size(); i++) {         解绑定已经bind的service
                LoadedApk.ServiceDispatcher sd = smap.valueAt(i);
                ServiceConnectionLeaked leak = new ServiceConnectionLeaked(
                        what + ” ” + who + ” has leaked ServiceConnection “
                        + sd.getServiceConnection() + ” that was originally bound here”);
                leak.setStackTrace(sd.getLocation().getStackTrace());
                Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
                if (reportRegistrationLeaks) {

                    StrictMode.onServiceConnectionLeaked(leak);
                }
                try {

                    ActivityManagerNative.getDefault().unbindService(
                            sd.getIServiceConnection());
                } catch (RemoteException e) {

                    // system crashed, nothing we can do
                }
                sd.doForget();
            }
        }
        mUnboundServices.remove(context);
        //Slog.i(TAG, “Service registrations: ” + mServices);

    }

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/195003.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 搭建本地私有pip源「建议收藏」

    搭建本地私有pip源「建议收藏」目的1、用于内网内的pip安装2、整理个人使用的python第三方库3、个人开发公用库搭建环境1、centos72、python2/python3搭建步骤(python2相同)1、安装python3.7下载地址:https://www.python.org/ftp/python/3.7.9/Python-3.7.9.tar.xz解压tar-xvJfPython-3.7.2.tar.xz创建编译安装目录mkdir/usr/local/python3

    2022年5月18日
    129
  • stata 求输出相关系数矩阵命令_一文读懂结果输出命令大全(上)

    stata 求输出相关系数矩阵命令_一文读懂结果输出命令大全(上)目录描述统计量helptabstat//Stata官方命令描述统计量组间均值差异检验helpttesthelpttable2helpestout相关分析命令helppwcorrhelppwcorr_a回归相关分析命令helpesttabhelpoutreg2helplogoutstata命令汇总helpsum2docx//输出基…

    2022年6月15日
    220
  • MySQL 上亿大表优化实践

    MySQL 上亿大表优化实践

    2022年2月13日
    43
  • 爬虫实战| 1宅男女神(秀人网专区)—让人心情愉悦的图片爬取 ![通俗易懂]

    爬虫实战| 1宅男女神(秀人网专区)—让人心情愉悦的图片爬取 ![通俗易懂]目标是宅男女神的美女图片板块下的秀人板块,页面上全部是该网站收录的美女图片分类,大概浏览了一下,发现各个杂志社的图片(妹子)质量最高,其中以秀人为首,所以决定爬取所有秀人板块下的图片.目标网页截图该网页这里显示只有5页,后面的页面在点击下一页后出现.为了过审还是打码了,本来都是穿着衣服的正经妹妹,兄弟们可别误会了~首先利用Chrome抓包第一步先利用抓包工具来判断我们要爬取的网站是动态数据还是静态数据.这里可以清楚的看到,当我们发起请求之后,所有我们需要的东西都已经加载

    2022年6月2日
    77
  • vue devtools使用教程_vue debug

    vue devtools使用教程_vue debug一般在utils文件夹下api.js文件里面写接口,接口环境判断varhref=window.location.href//两者都可以拿到当前运行URL链接//varhost=window.location.hostlet_ipcc_cst;const_sysServer=(/(creditcard.ecitic.com)/i.test(location.origin))?’https://creditcard.ecitic.com’:’https://e.test.ban

    2022年9月29日
    2
  • Java8中String.join方法,让我们的代码更优美

    Java8中String.join方法,让我们的代码更优美强烈推荐一个大神的人工智能的教程:http://www.captainbed.net/zhanghan【前言】距Java8(14年3月19日)发布马上就四年了;相信接触过java8的人,会对它的很多新的特性新的方法有感觉;自然我也不例外;今天就一起给大家分享一个java8中的方法。【善用新语法,让代码更优美】一、简洁:最近自己在做项目的时候学习到很多技巧…

    2022年6月4日
    47

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号