Android13 Context registerReceiver流程分析

本文详细解析了Android中Context的registerReceiver方法的实现过程,涉及ContextImpl、LoadedApk、BroadcastReceiver、IntentFilter等关键组件,重点介绍了如何通过getReceiverDispatcher获取调度器并调用ActivityManager的registerReceiverWithFeature方法注册广播接收器。
摘要由CSDN通过智能技术生成

Context的registerReceiver用于注册BroadcastReceiver,代码如下:

//frameworks/base/core/java/android/content/Context.java
public abstract class Context {
    public abstract Intent registerReceiver(@Nullable BroadcastReceiver receiver,
                                            IntentFilter filter);
}

Context是抽象类,由其子类ContextImpl实现:

//frameworks/base/core/java/android/content/ContextImpl.java
class ContextImpl extends Context {
    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        return registerReceiver(receiver, filter, null, null);
    }
}

调用重载方法:

//frameworks/base/core/java/android/content/ContextImpl.java
class ContextImpl extends Context {
    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
            String broadcastPermission, Handler scheduler) {
        return registerReceiverInternal(receiver, getUserId(),
                filter, broadcastPermission, scheduler, getOuterContext(), 0);
    }
}

调用registerReceiverInternal方法:

//frameworks/base/core/java/android/content/ContextImpl.java
class ContextImpl extends Context {
    final @NonNull LoadedApk mPackageInfo;
    private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
            IntentFilter filter, String broadcastPermission,
            Handler scheduler, Context context, int flags) {
        IIntentReceiver rd = null;
 // 将BroadcastReceiver存储到LoadedApk.ReceiverDispatcher对象里,并通过LoadedApk.ReceiverDispatcher.InnerReceiver的Binder对象和AMS进行通信
        if (receiver != null) {
            if (mPackageInfo != null && context != null) {
                if (scheduler == null) {
                    scheduler = mMainThread.getHandler();
                }
  // 获取IntentReceiver Binder对象
                rd = mPackageInfo.getReceiverDispatcher(
                    receiver, context, scheduler,
                    mMainThread.getInstrumentation(), true); //获取调度器
            } else {
                if (scheduler == null) {
                    scheduler = mMainThread.getHandler();
                }
  // 获取IntentReceiver Binder对象
                rd = new LoadedApk.ReceiverDispatcher(
                        receiver, context, scheduler, null, true).getIIntentReceiver();
            }
        }
        try {
            ActivityThread thread = ActivityThread.currentActivityThread(); //创建ActivityThread
            Instrumentation instrumentation = thread.getInstrumentation(); //取得Instrumentation
            if (instrumentation.isInstrumenting()
                    && ((flags & Context.RECEIVER_NOT_EXPORTED) == 0)) {
                flags = flags | Context.RECEIVER_EXPORTED;
            }
     // 调用AMS.registerReceiverWithFeature
            final Intent intent = ActivityManager.getService().registerReceiverWithFeature(
                    mMainThread.getApplicationThread(), mBasePackageName, getAttributionTag(),
                    AppOpsManager.toReceiverId(receiver), rd, filter, broadcastPermission, userId,
                    flags); 
            if (intent != null) {
                intent.setExtrasClassLoader(getClassLoader());
                // TODO: determine at registration time if caller is
                // protecting themselves with signature permission
                intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent),
                        getAttributionSource());
            }
            return intent;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
}

上述方法主要处理如下:

1、调用mPackageInfo(LoadedApk )的getReceiverDispatcher方法,获取调度器

2、调用调用ActivityManager的getService获取IActivityManager接口,然后调用IActivityManager的registerReceiverWithFeature方法

下面分别进行确认:

LoadedApk getReceiverDispatcher

调用mPackageInfo(LoadedApk )的getReceiverDispatcher方法,获取调度器:

//frameworks/base/core/java/android/app/LoadedApk.java
public final class LoadedApk {
    public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
            Context context, Handler handler,
            Instrumentation instrumentation, boolean registered) {
        synchronized (mReceivers) {
            LoadedApk.ReceiverDispatcher rd = null;
            ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
            if (registered) {
                map = mReceivers.get(context);
                if (map != null) {
                    rd = map.get(r);
                }
            }
            if (rd == null) {
                rd = new ReceiverDispatcher(r, context, handler,
                        instrumentation, registered);
                if (registered) {
                    if (map == null) {
                        map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
                        mReceivers.put(context, map);
                    }
                    map.put(r, rd);
                }
            } else {
                rd.validate(context, handler);
            }
            rd.mForgotten = false;
            return rd.getIIntentReceiver();
        }
    }
}

new ReceiverDispatcher

通过new的方式创建ReceiverDispatcher,加入将其加入到ArrayMap中,使其与BroadcastReceiver一一对应,ReceiverDispatcher的构造方法如下:

//frameworks/base/core/java/android/app/LoadedApk.java
public final class LoadedApk {
    static final class ReceiverDispatcher {
        ReceiverDispatcher(BroadcastReceiver receiver, Context context,
                Handler activityThread, Instrumentation instrumentation,
                boolean registered) {
            if (activityThread == null) {
                throw new NullPointerException("Handler must not be null");
            }


            mIIntentReceiver = new InnerReceiver(this, !registered);
            mReceiver = receiver;
            mContext = context;
            mActivityThread = activityThread;
            mInstrumentation = instrumentation;
            mRegistered = registered;
            mLocation = new IntentReceiverLeaked(null);
            mLocation.fillInStackTrace();
        }
    }
}

调用ActivityManager的getService获取IActivityManager接口,然后调用IActivityManager的registerReceiverWithFeature方法,ActivityManager的getService方法如下:

public class ActivityManager {
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }
}

ActivityManagerService registerReceiverWithFeature

调用IActivityManager的bindServiceInstance方法,IActivityManager是一个接口由ActivityManagerService实现,调用ActivityManagerService的registerReceiverWithFeature方法:

Android13 ActivityManagerService registerReceiverWithFeature流程分析-CSDN博客

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值