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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 亿图图示用户名和密钥激活码【最新永久激活】2022.02.13

    (亿图图示用户名和密钥激活码)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年4月1日
    20.2K
  • rime android汉字,Rime输入法

    rime android汉字,Rime输入法Rime输入法的安卓版又叫同文输入法,是Rime输入法好几个版本中的一个,适合喜欢调校的人。界面比较简洁,也很小巧,功能就是输入,偏英文输入,支持调整颜色更改外观。Rime输入法简介RIME/中州韻輸入法引擎,是一個跨平臺的輸入法算法框架。基於這一框架,Rime開發者與其他開源社區的參與者在Windows、MacOSX、Linux、Android平臺上創造了不同的輸入法前端實現。Rime…

    2022年7月12日
    32
  • 美化包软件_手机音量进度条插件下载

    美化包软件_手机音量进度条插件下载前言在我们进行自动化测试的时候,用例往往是成百上千,执行的时间是几十分钟或者是小时级别。有时,我们在调试那么多用例的时候,不知道执行到什么程度了,而pytest-sugar插件能很好解决我们的痛点。

    2022年7月28日
    11
  • python中bool函数用法_在python中bool函数的取值方法「建议收藏」

    python中bool函数用法_在python中bool函数的取值方法「建议收藏」bool是Boolean的缩写,只有真(True)和假(False)两种取值bool函数只有一个参数,并根据这个参数的值返回真或者假。1.当对数字使用bool函数时,0返回假(False),任何其他值都返回真。>>>bool(0)False>>>bool(1)True>>>bool(-1)True>>>bool(213…

    2022年4月30日
    62
  • oracle sql 字符串拼接_mysql将字符串和数字拼接

    oracle sql 字符串拼接_mysql将字符串和数字拼接一、MySQL在Java中我们通常用加号”+”来实现字符串的拼接,MySQL中也可以使用”+”来实现,比如:先加入测试数据CREATETABLEtest(idINT,nameVARCHAR(10),scoreFLOAT);INSERTINTOtestVALUES(1,’zhang’,98);INSERTINTOtestVALUES(2,’li’,95);Demo1SELECT…

    2022年9月2日
    7
  • B样条曲线与贝塞尔曲线学习笔记

    B样条曲线与贝塞尔曲线学习笔记贝塞尔曲线基本公式:B(t)=∑i=0n(in)Pi(1−t)n−iti,t∈[0,1]基本公式:B(t)=\sum_{i=0}^{n}\Big({_i^n}\Big)P_i(1-t)^{n-i}t^i,t\in[0,1]基本公式:B(t)=i=0∑n​(in​)Pi​(1−t)n−iti,t∈[0,1]三次贝塞尔曲线:B(t)=P0(1−t)3+3P1t(1−t)2+3P2t2(1−t)…

    2022年6月18日
    26

发表回复

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

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