hi,粉丝朋友大家好!
今天是2-8号,也是我春节第一天正式开工的日子,在这里首先祝大家新的一年技术进步,与千里马共同学习共同进步,共同升职加薪。今天要给大家分享的一个课题是大家都很熟悉的广播。
这里将要分为2个部分来对广播进行分析:
入门课,实战课,跨进程专题
ps需要学习深入framework课程和课程优惠
(可以加我qq:2102309716 优惠购买)
1、广播发送部分
一般我们正常使用发送广播都会有调用一个context的sendBroadcas,方法原型如下:
public void sendBroadcast(Intent intent);
这里我们一般就是只想要传递一个intent参数既可以,这里调用context方法,其实和上一节讲解service一样,最后都会调用到ContextImpl方法中的sendBroadcast:
@Override
public void sendBroadcast(Intent intent) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
intent.prepareToLeaveProcess(this);//只是对intent进行一下预处理
ActivityManager.getService().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
getUserId());//最后调用到了AMS里面的broadcastIntent
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
下面来看AMS的broadcastIntent方法,这里我们暂时只分析最常见的一类平行广播,不看有序部分,感兴趣可以自己分析:
final int broadcastIntentLocked(ProcessRecord callerApp,
String callerPackage, Intent intent, String resolvedType,
IIntentReceiver resultTo, int resultCode, String resultData,
Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid,
int realCallingPid, int userId, boolean allowBackgroundActivityStarts) {
//省略部分
// Figure out who all will receive this broadcast.
List receivers = null;
List<BroadcastFilter> registeredReceivers = null;//获取接受者的List
// Need to resolve the intent to interested receivers...
if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
== 0) {
receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
}
if (intent.getComponent() == null) {
//具体根据intent进行filter获取接受者的List
if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
// Query one target user at a time, excluding shell-restricted users
for (int i = 0; i < users.length; i++) {
if (mUserController.hasUserRestriction(
UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
continue;
}
List<BroadcastFilter> registeredReceiversForUser =
mReceiverResolver.queryIntent(intent,
resolvedType, false /*defaultOnly*/, users[i]);
if (registeredReceivers == null) {
registeredReceivers = registeredReceiversForUser;
} else if (registeredReceiversForUser != null) {
registeredReceivers.addAll(registeredReceiversForUser);
}
}
} else {
registeredReceivers = mReceiverResolver.queryIntent(intent,
resolvedType, false /*defaultOnly*/, userId);
}
}
if (!ordered && NR > 0) {
final BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
resultCode, resultData, resultExtras, ordered, sticky, false, userId,
allowBackgroundActivityStarts, timeoutExempt);//构造出一个BroadcastRecord
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
final boolean replaced = replacePending
&& (queue.replaceParallelBroadcastLocked(r) != null);
// Note: We assume resultTo is null for non-ordered broadcasts.
if (!replaced) {
queue.enqueueParallelBroadcastLocked(r);//插入平行广播队列
queue.scheduleBroadcastsLocked();
}
registeredReceivers = null;
NR = 0;
}
//省略部分
return ActivityManager.BROADCAST_SUCCESS;
}
接下来看看最重要的enqueueParallelBroadcastLocked和scheduleBroadcastsLocked部分:
public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
mParallelBroadcasts.add(r);//这里动作很简单就是把BroadcastRecord插入到mParallelBroadcasts这个list
enqueueBroadcastHelper(r);
}
接下来看scheduleBroadcastsLocked:
public void scheduleBroadcastsLocked() {
//省略部分
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}
这里其实就只是发送了一个BROADCAST_INTENT_MSG消息:
来看看对这个消息的处理
private final class BroadcastHandler extends Handler {
public BroadcastHandler(Looper looper) {
super(looper, null, true);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BROADCAST_INTENT_MSG: {
if (DEBUG_BROADCAST) Slog.v(
TAG_BROADCAST, "Received BROADCAST_INTENT_MSG ["
+ mQueueName + "]");
processNextBroadcast(true);//调用了processNextBroadcast方法
} break;
case BROADCAST_TIMEOUT_MSG: {
synchronized (mService) {
broadcastTimeoutLocked(true);
}
} break;
}
}
}
这里我们来看processNextBroadcast:
final void processNextBroadcast(boolean fromMsg) {
synchronized (mService) {
processNextBroadcastLocked(fromMsg, false);
}
}
重点看看processNextBroadcastLocked:
final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
BroadcastRecord r;
while (mParallelBroadcasts.size() > 0) {
r = mParallelBroadcasts.remove(0);//获取平行广播的BroadcastRecord对象
final int N = r.receivers.size();
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);//这里是核心调用了deliverToRegisteredReceiverLocked方法
}
addBroadcastToHistoryLocked(r);
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
+ mQueueName + "] " + r);
}
//省略部分
}
下面来看deliverToRegisteredReceiverLocked方法:
private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
BroadcastFilter filter, boolean ordered, int index) {
//省略部分
try {
if (filter.receiverList.app != null && filter.receiverList.app.inFullBackup) {
//省略部分
} else {
r.receiverTime = SystemClock.uptimeMillis();
maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r);
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.userId);
//最重要调用了performReceiveLocked
//省略部分
}
//省略部分
} catch (RemoteException e) {
//省略部分
}
}
接下来重点看performReceiveLocked:
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) {
if (app.thread != null) {
try {
//调用到了具体应用进程的scheduleRegisteredReceiver方法
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.getReportedProcState());
} catch (RemoteException ex) {
//省略
}
} else {
throw new RemoteException("app.thread must not be null");
}
} else {
receiver.performReceive(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
}
}
这里的scheduleRegisteredReceiver方法是在应用进程的ActivityThread类中实现的:
// This function exists to make sure all receiver dispatching is
// correctly ordered, since these are one-way calls and the binder driver
// applies transaction ordering per object for such calls.
public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
int resultCode, String dataStr, Bundle extras, boolean ordered,
boolean sticky, int sendingUser, int processState) throws RemoteException {
updateProcessState(processState, false);
receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
sticky, sendingUser);
}
这里会调用到receiver的performReceive方法,其中IIntentReceiver实际实在LoadedApk.java中:
final static class InnerReceiver extends IIntentReceiver.Stub {
//省略
@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
final LoadedApk.ReceiverDispatcher rd;
//省略
if (rd != null) {
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky, sendingUser);
} else {
//省略
}
}
}
这里就调用了 LoadedApk.ReceiverDispatcher的performReceive方法,其中ReceiverDispatcher也在LoadedApk.java:
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
final Args args = new Args(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
//省略
if (intent == null || !mActivityThread.post(args.getRunnable())) {
//这句mActivityThread.post(args.getRunnable())是核心
if (mRegistered && ordered) {
IActivityManager mgr = ActivityManager.getService();
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing sync broadcast to " + mReceiver);
args.sendFinished(mgr);
}
}
}
这里mActivityThread.post(args.getRunnable())是核心,就是往主线程post了一个runnable,我们来看getRunnable这个方法:
public final Runnable getRunnable() {
return () -> {
//省略部分
try {
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
intent.prepareToEnterProcess();
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
receiver.onReceive(mContext, intent);//调用到具体应用广播接收器的onReceive
} catch (Exception e) {
//省略部分
};
}
}
主要就 receiver.onReceive(mContext, intent)这里就调用到具体应用广播接收器的onReceive,也就是我们经常onReceive写处理业务地方
总结图如下:
2、广播注册接受部分
下一节讲解