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);

    }

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

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