Android-Framework学习笔记(九)Broadcast的注册、发送和接收过程,面试官都被搞懵了

ContextWrapper#registerReceiver()

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

在前面Android Framework学习笔记(八)Service的启动/绑定过程
这篇文章中我们已经分析了,mBase具体指向就是ContextImpl。

frameworks/base/core/java/android/app/ContextImpl.java

ContextImpl#registerReceiver()

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

@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
String broadcastPermission, Handler scheduler) {
return registerReceiverInternal(receiver, getUserId(),
filter, broadcastPermission, scheduler, getOuterContext()); //1
}

注释1最终会调用到registerReceiverInternal。

ContextImpl#registerReceiverInternal()

private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context) {
IIntentReceiver rd = null;
if (receiver != null) {
if (mPackageInfo != null && context != null) { //1
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true); //2
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = new LoadedApk.ReceiverDispatcher(
receiver, context, scheduler, null, true).getIIntentReceiver(); //3
}
}
try {
final Intent intent = ActivityManagerNative.getDefault().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName,
rd, filter, broadcastPermission, userId); //4
if (intent != null) {
intent.setExtrasClassLoader(getClassLoader());
intent.prepareToEnterProcess();
}
return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

注释1处判断如果LoadedApk类型的mPackageInfo不等于null并且context不等null就调用注释2处的代码通过mPackageInfo的getReceiverDispatcher方法获取rd对象,否则就调用注释3处的代码来创建rd对象。
注释2和3的代码的目的都是要获取IIntentReceiver类型的rd对象,IIntentReceiver是一个Binder接口,用于进行跨进程的通信,它的具体实现在LoadedApk.ReceiverDispatcher.InnerReceiver。

frameworks/base/core/java/android/app/LoadedApk.java

ReceiverDispatcher

static final class ReceiverDispatcher {
final static class InnerReceiver extends IIntentReceiver.Stub {
final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
final LoadedApk.ReceiverDispatcher mStrongRef;
InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
mStrongRef = strong ? rd : null;
}

}

}

继续来看registerReceiverInternal函数的注释4,其实是通过Binder调用的AMS的registerReceiver方法。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

ActivityManagerService#registerReceiver()

public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {

ArrayList stickyIntents = null;
ProcessRecord callerApp = null;
int callingUid;
int callingPid;
synchronized(this) {

Iterator actions = filter.actionsIterator(); //1
if (actions == null) {
ArrayList noAction = new ArrayList(1);
noAction.add(null);
actions = noAction.iterator();

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值