BroadCastReciver 源码分析
上篇记录了activity启动流程的关键节点代码,本篇同样只是记录广播源码的关键节点代码
一、发送广播
broadCast 分为普通广播和有序广播,普通广播 发送后注册该广播的接收器都能接收到,而有序广播不同的是会根据接收器的优先级依次收到广播,并可中断广播继续向下发送
以下做了一个简单的脑图,做为流程图,可以大体看明白广播的传递流程
关键节点源码
sendBroadCast只是在Context中做了定义,而Context的实现类是Contextimpl,以下代码我们可以看到是直接将参数给到了AMS处理
@Override
public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
String[] receiverPermissions = receiverPermission == null ? null
: new String[] {receiverPermission};
try {
intent.prepareToLeaveProcess(this);
//调用AMS
ActivityManager.getService().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, receiverPermissions, appOp, null, false, false,
getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
通过层层调用我们在方法broadcastIntentLocked中会看到以下关键代码:
其中 queue.enqueueParallelBroadcastLocked的实现,将该条记录存放到了列表中
public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
this.mParallelBroadcasts.add(r);
}
scheduleBroadcastsLocked的实现,这里通过handler发送了一个消息
public void scheduleBroadcastsLocked() {
if (!this.mBroadcastsScheduled) {
this.mHandler.sendMessage(this.mHandler.obtainMessage(200, this));
this.mBroadcastsScheduled = true;
}
}
通过这个消息会调用processNextBroadcast该方法,会调用到deliverToRegisteredReceiverLocked该方法,通过该方法会调用到performReceiveLocked方法
performReceiveLocked方法:
private static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
if (app != null && app.thread != null) {
//IApplicationThread 的实现ActivityTread
//这里开始从AMS回调到应用中
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, data, extras, ordered, sticky, sendingUser);
} else {
receiver.performReceive(intent, resultCode, data, extras, ordered, sticky, sendingUser);
}
}
ActivityThread中的实现:
public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, int resultCode, String dataStr, Bundle extras, boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
//IIntentReceiver的实现在LoadedApk类
receiver.performReceive(intent, resultCode, dataStr, extras, ordered, sticky, sendingUser);
}
LoadedApk中的实现,开始分发广播
public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
LoadedApk.ReceiverDispatcher.Args args = new LoadedApk.ReceiverDispatcher.Args(intent, resultCode, data, extras, ordered, sticky, sendingUser);
if (!this.mActivityThread.post(args) && this.mRegistered && ordered) {
IActivityManager mgr = ActivityManagerNative.getDefault();
args.sendFinished(mgr);
}
}
args 这个Runnable核心逻辑代码:
public void run() {
BroadcastReceiver receiver = ReceiverDispatcher.this.mReceiver;
boolean ordered = this.mOrdered;
IActivityManager mgr = ActivityManagerNative.getDefault();
Intent intent = this.mCurIntent;
this.mCurIntent = null;
if (receiver != null && !ReceiverDispatcher.this.mForgotten) {
Trace.traceBegin(64L, "broadcastReceiveReg");
try {
ClassLoader cl = ReceiverDispatcher.this.mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
this.setExtrasClassLoader(cl);
receiver.setPendingResult(this);
receiver.onReceive(ReceiverDispatcher.this.mContext, intent);
} catch (Exception var6) {
if (ReceiverDispatcher.this.mRegistered && ordered) {
this.sendFinished(mgr);
}
if (ReceiverDispatcher.this.mInstrumentation == null || !ReceiverDispatcher.this.mInstrumentation.onException(ReceiverDispatcher.this.mReceiver, var6)) {
Trace.traceEnd(64L);
throw new RuntimeException("Error receiving broadcast " + intent + " in " + ReceiverDispatcher.this.mReceiver, var6);
}
}
if (receiver.getPendingResult() != null) {
this.finish();
}
Trace.traceEnd(64L);
} else {
if (ReceiverDispatcher.this.mRegistered && ordered) {
this.sendFinished(mgr);
}
}
}
}
自此整个广播发送流程就结束了
二、 注册接收广播
注册比较简单,通过将参数交给AMS,保存到列表中,注册成功
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context, int flags) {
IIntentReceiver rd = null;
if (receiver != null) {
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = new LoadedApk.ReceiverDispatcher(
receiver, context, scheduler, null, true).getIIntentReceiver();
}
}
try {
//AMS处理
final Intent intent = ActivityManager.getService().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
broadcastPermission, userId, flags);
if (intent != null) {
intent.setExtrasClassLoader(getClassLoader());
intent.prepareToEnterProcess();
}
return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}