一定要用相同的Context 对同一个receiver进行registerReceiver与unregisterReceiver吗?

博客探讨了在Android中动态注册和反注册BroadcastReceiver时是否必须使用相同Context的问题。通过对Application和Activity创建过程的分析,发现它们的ContextImpl实例不同,但不影响使用不同Context进行注册和反注册,因为最终都是通过ActivityManagerNative来处理。尽管如此,考虑到Android的碎片化,建议使用ApplicationContext进行操作。
摘要由CSDN通过智能技术生成

最近在开发一些功能,突然想到在动态注册和反注册receiver的时候一定要用相同的context吗?我不敢肯定咨询了同事,得到的答案是不行的,然而为了进一步佐证他的观点我自己尝试了一下。也就是查了一下相关代码。

众所周知android的应用程序在ActivityThread的public static void main(String[] args)中开始调用我们写的代码,Application 、Activity、Service等等。

我们都知道在动态注册和反注册receiver的时候需要一个context,然而无论Application还是Activity都是直接或间接继承自ContextWrapper,而ContextWrapper继承自Context。

在ContextWrapper中

public class ContextWrapper extends Context {
   
    Context mBase;

    public ContextWrapper(Context base) {
        mBase = base;
    }

    /**
     * Set the base context for this ContextWrapper.  All calls will then be
     * delegated to the base context.  Throws
     * IllegalStateException if a base context has already been set.
     * 
     * @param base The new base context for this wrapper.
     */
    protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }

其中mBase是关键,因为

    @Override
    public Intent registerReceiver(
        BroadcastReceiver receiver, IntentFilter filter) {
        return mBase.registerReceiver(receiver, filter);
    }


    @Override
    public void unregisterReceiver(BroadcastReceiver receiver) {
        mBase.unregisterReceiver(receiver);
    }

都是通过mBase来实现的。ok现在关键点就是看在给Activity和Application的mBase赋值时候是不是使用同一个mBase就可以了。

ok我们先看Application的创建过程

public static void main(String[] args) {
        SamplingProfilerIntegration.start();

        // CloseGuard defaults to true and can be quite spammy.  We
        // disable it here, but selectively enable it later (via
        // StrictMode) on debug builds, but using DropBox, not logs.
        CloseGuard.setEnabled(false);

        Environment.initForCurrentUser();

        // Set the reporter for event logging in libcore
        EventLogger.setReporter(new EventLoggingReporter());

        Security.addProvider(new AndroidKeyStoreProvider());

        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);

        Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

其中
ActivityThread thread = new ActivityThread();
thread.attach(false);

    private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            ViewRootImpl.addFirstDrawHandler(new Runnable() {
                @Override
                public void run() {
                    ensureJitEnabled();
                }
            });
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                // Ignore
            }
            // Watch for getting close to heap limit.
            BinderInternal.addGcWatcher(new Runnable() {
                @Override public void run() {
                    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值