目录
前言
本次分析一下Android P开机后发送静态广播源码分析,记录一下,方便自己查阅。
部分流程跟前面的源码分析《startActivity源码分析》和《startService源码分析》都比较类似,所以重复的步骤就省略。
PS:启动startActivity的比较复杂,流程多,但搞懂了这个,startService和sendBroadcast的分析就更简单。
正文
静态和动态广播区别
-
生存期
静态广播的生存期比动态广播的长很多。
-
优先级
动态广播的优先级比静态广播高。
-
注册方式
(1)静态广播需要AndroidManifest.xml注册和声明
(2)动态广播通过registerReceiver()注册和unregisterReceiver()反注册
这先分析静态广播
#MainActivity.java中 Intent intent = new Intent(); intent.setPackage("com.biumall.server"); intent.setAction("com.biumall.server.ACTION_ONE"); sendBroadcast(intent);
静态广播注册,在AndroidManifest.xml中添加
<receiver android:name="com.biumall.server.receiver.StaticReceiver" android:enabled="true" android:exported="true"> <intent-filter android:priority="9999"> <action android:name="com.biumall.server.ACTION_ONE" /> </intent-filter> </receiver>
广播的发送最终在ContextImpl.java中,我们从这里开始跟踪。
ContextImpl.java
sendBroadcast()
@Override public void sendBroadcast(Intent intent) { warnIfCallingFromSystemProcess(); String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); try { intent.prepareToLeaveProcess(this); //ActivityManager.getService()获取的是ActivityManagerService ActivityManager.getService().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false, getUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
进入ActivityManagerService.broadcastIntent()
ActivityManagerService.java
broadcastIntent()
public final int broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, boolean serialized, boolean sticky, int userId) { //略 synchronized(this) { //验证广播合法性 intent = verifyBroadcastLocked(intent); //略 //继续,进入broadcastIntentLocked int res = broadcastIntentLocked(callerApp, callerApp != null ? callerApp.info.packageName : null, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, requiredPermissions, appOp, bOptions, serialized, sticky, callingPid, callingUid, userId); Binder.restoreCallingIdentity(origId); return res; } }
broadcastIntentLocked()
很长,不重要的大部分省略。
@GuardedBy("this") 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 userId) { intent = new Intent(intent); //略 发送的是普通的广播, final String action = intent.getAction(); //bOptions为null if (bOptions != null) { //略 } final boolean isProtectedBroadcast; try { //没有添加入包含名单,false isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action); } catch (RemoteException e) { return ActivityManager.BROADCAST_SUCCESS; } final boolean isCallerSystem; //判断是否系统应用发送 switch (UserHandle.getAppId(callingUid)) { case ROOT_UID: case SYSTEM_UID: case PHONE_UID: case BLUETOOTH_UID: case NFC_UID: case SE_UID: isCallerSystem = true; break; default: isCallerSystem = (callerApp != null) && callerApp.persistent; break; } //我这是系统应用发送 if (!isCallerSystem) { //略 } //略 //不是粘性广播,上面传入的也是false if (sticky) { //略 } //略 List<BroadcastFilter> registeredReceivers = null; //获取广播接收者list if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)== 0) { //这部分搜集的后面有空跟着一下 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users); } //发送广播时没有指定 if (intent.getComponent() == null) { //略 } //false final boolean replacePending = (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; //registeredReceivers为null,没有进入上面的赋值 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; //传入的ordered = false, NR= 0,跳过 if (!ordered && NR > 0) { //略 } //略 //isCallerSystem为true没我这是系统应用发送广播 if (isCallerSystem) { //检查权限 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, isProtectedBroadcast, receivers); } //receivers广播接收者列表,不为null,且size()大于0 if ((receivers != null && receivers.size() > 0) || resultTo != null) { //广播队列,这里会判断是前台广播还是后台广播 BroadcastQueue queue = broadcastQueueForIntent(intent); //广播记录 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, callingPid, callingUid, callerInstantApp, resolvedType, requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId); //此处replacePending为false final BroadcastRecord oldRecord = replacePending ? queue.replaceOrderedBroadcastLocked(r) : null; //oldrecord为null if (oldRecord != null) { //略 } else { //[重] //添加BroadcastRecord到队列 mOrderedBroadcasts.add(); queue.enqueueOrderedBroadcastLocked(r); //安排发送广播 queue.scheduleBroadcastsLocked(); } } else { //略 } return ActivityManager.BROADCAST_SUCCESS; }
BroadcastQueue.java
enqueueOrderedBroadcastLocked()
public void enqueueOrderedBroadcastLocked(BroadcastRecord r) { //添加广播到mOrderedBroadcasts mOrderedBroadcasts.add(r); enqueueBroadcastHelper(r); }
scheduleBroadcastsLocked()
public void scheduleBroadcastsLocked() { if (mBroadcastsScheduled) { return; } //发送BROADCAST_INTENT_MSG mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this)); //这里会吧mBroadcastsScheduled置为true mBroadcastsScheduled = true; }
handleMessage()
@Override public void handleMessage(Message msg) { switch (msg.what) { case BROADCAST_INTENT_MSG: { //发送下一个广播 processNextBroadcast(true); } break; case BROADCAST_TIMEOUT_MSG: { //广播超时处理 synchronized (mService) { broadcastTimeoutLocked(true); } } break; } }
processNextBroadcast()
final void processNextBroadcast(boolean fromMsg) { synchronized (mService) { //fromMsg=true processNextBroadcastLocked(fromMsg, false); } }
processNextBroadcastLocked()
进入这里就分两步了
-
广播接收者的进程启动过,就走processCurBroadcastLocked()
-
广播接收者的进程没启动过,需先启动进程startProcessLocked(),然后出了队列中的广播
如果进程没有启动,需要先启动(多了这部分),最后也会启动processCurBroadcastLocked()
当然,我们下面也发现了,优先处理了动态注册的的广播,然后再去执行后面静态广播。
final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) { BroadcastRecord r; //略 //fromMsg传入的为true if (fromMsg) { mBroadcastsScheduled = false; } //处理动态注册的广播,我们这是第一次给应用发静态广播 //这里size()=0 while (mParallelBroadcasts.size() > 0) { r = mParallelBroadcasts.remove(0); r.dispatchTime = SystemClock.uptimeMillis(); r.dispatchClockTime = System.currentTimeMillis(); 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); } addBroadcastToHistoryLocked(r); } //mPendingBroadcast为null //mPendingBroadcast是在后面进行赋值,的表示Pending中的广播。 //不过,这里不是很了解,跳过吧 if (mPendingBroadcast != null) { //略 } boolean looped = false; do { //mOrderedBroadcasts在enqueueOrderedBroadcastLocked添加的 //mOrderedBroadcasts.size()>0 if (mOrderedBroadcasts.size() == 0) { //略 return; } //获取列表中的第一个 r = mOrderedBroadcasts.get(0); boolean forceReceive = false; //numReceivers有一个,就是我们要发送的广播 //当然,我们只针对我们发送的分析。 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0; //mService.mProcessesReady为true // r.dispatchTime=0,还在队列中,没法安排发送 if (mService.mProcessesReady && r.dispatchTime > 0) { //略 } //r.state 为 0 ,BroadcastRecord.IDLE 空闲 if (r.state != BroadcastRecord.IDLE) { return; } //r.receivers 广播接收者 //r.nextReceiver 下一个广播接收者,我这只有一个,所以为0 //r.resultAbort false 终止广播值?这不太懂 //forceReceive false 强制接受? 哈哈也不懂,, //反正,不满足条件 if (r.receivers == null || r.nextReceiver >= numReceivers || r.resultAbort || forceReceive) { //略 } } while (r == null); //上面知道nextReceiver为0 //先赋值,后++,所以recIdx = 0 int recIdx = r.nextReceiver++; //赋值接收时间 r.receiverTime = SystemClock.uptimeMillis(); //recIdx为0 if (recIdx == 0) { //设置投递时间 r.dispatchTime = r.receiverTime; r.dispatchClockTime = System.currentTimeMillis(); } //mPendingBroadcastTimeoutMessage为false //还没设置超时广播 if (! mPendingBroadcastTimeoutMessage) { long timeoutTime = r.receiverTime + mTimeoutPeriod; //设置广播超时60s时ANR(mTimeoutPeriod = 60) setBroadcastTimeoutLocked(timeoutTime); } final BroadcastOptions brOptions = r.options; //就是获取第一个广播接收者 final Object nextReceiver = r.receivers.get(recIdx); // nextReceiver是ResolveInfo对象。,不是BroadcastFilter实例 //不进入下面 if (nextReceiver instanceof BroadcastFilter) { //略 return; } ResolveInfo info =(ResolveInfo)nextReceiver; ComponentName component = new ComponentName( info.activityInfo.applicationInfo.packageName, info.activityInfo.name); boolean skip = false; //略 //获取进程记录 ProcessRecord app = mService.getProcessRecordLocked(targetProcess, info.activityInfo.applicationInfo.uid, false); //开头说了,我开机第一次就发送静态广播,接收广播的进程是没提前启动的 //因此获取的app是为null //略 r.manifestCount++; r.delivery[recIdx] = BroadcastRecord.DELIVERY_DELIVERED; r.state = BroadcastRecord.APP_RECEIVE; r.curComponent = component; r.curReceiver = info.activityInfo; //略 // Broadcast is being executed, its package can't be stopped. try { AppGlobals.getPackageManager().setPackageStoppedState( r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid)); } catch (RemoteException e) { } catch (IllegalArgumentException e) { Slog.w(TAG, "processNextBroadcastLocked Failed trying to unstop package " + r.curComponent.getPackageName() + ": " + e); } //如果不为null,表示进程已经启动 //如果启动了就走这里 if (app != null && app.thread != null && !app.killed) { try { app.addPackage(info.activityInfo.packageName, info.activityInfo.applicationInfo.versionCode, mService.mProcessStats); //处理当前广播 processCurBroadcastLocked(r, app, skipOomAdj); return; } catch (RemoteException e) { Slog.w(TAG, "processNextBroadcastLocked Exception when sending broadcast to " + r.curComponent, e); } catch (RuntimeException e) { logBroadcastReceiverDiscardLocked(r); finishReceiverLocked(r, r.resultCode, r.resultData, r.resultExtras, r.resultAbort, false); scheduleBroadcastsLocked(); r.state = BroadcastRecord.IDLE; return; } } //走这里是进程没有启动 //启动新的进程ActivityManagerService.startProcessLocked() if ((r.curApp=mService.startProcessLocked(targetProcess, info.activityInfo.applicationInfo, true, r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND, "broadcast", r.curComponent, (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false)) == null) { //启动失败就走这里,否则不进来 //略 return; } //mPendingBroadcast赋值,记录BroadcastRecord mPendingBroadcast = r; mPendingBroadcastRecvIndex = recIdx; }
由于开头说了,我们是第一次发送静态广播,也即是App=null
也就是执行ActivityManagerService.startProcessLocked()流程。
进程的启动
这部分跟《》重合了,都是一样的流程。最后启动ActivityThread.main()。
而ActivityThread.main()到ActivityManagerService.attachApplicationLocked()这部分代码跟《》和《》基本一致。
因此,我们直接跳过重复的部分,直接进入ActivityManagerService.attachApplicationLocked()
ActivityManagerService.java
attachApplicationLocked()
@GuardedBy("this") private final boolean attachApplicationLocked(IApplicationThread thread, int pid, int callingUid, long startSeq) { //重复部分略,有需要的可看对应文章 //启动Activity if (normalMode) { try { //Activity if (mStackSupervisor.attachApplicationLocked(app)) { didSomething = true; } } catch (Exception e) { badApp = true; } } //启动服务 if (!badApp) { try { //Service didSomething |= mServices.attachApplicationLocked(app, processName); } catch (Exception e) { badApp = true; } } //启动广播 if (!badApp && isPendingBroadcastProcessLocked(pid)) { try { //Broadcasts didSomething |= sendPendingBroadcastsLocked(app); } catch (Exception e) { badApp = true; } } //略 return true; }
这里我们只关注广播的发送
if (!badApp && isPendingBroadcastProcessLocked(pid)) { try { didSomething |= sendPendingBroadcastsLocked(app); } catch (Exception e) { badApp = true; } }
sendPendingBroadcastsLocked()
// The app just attached; send any pending broadcasts that it should receive boolean sendPendingBroadcastsLocked(ProcessRecord app) { boolean didSomething = false; for (BroadcastQueue queue : mBroadcastQueues) { //根据app进行查询前台和后台的BroadcastQueue //看BroadcastQueue.sendPendingBroadcastsLocked() didSomething |= queue.sendPendingBroadcastsLocked(app); } return didSomething; }
mBroadcastQueues包含两个变量,在ActivityManagerService()中初始化
public ActivityManagerService(Context systemContext) { //略 //BROADCAST_FG_TIMEOUT 前台 10s mFgBroadcastQueue = new BroadcastQueue(this, mHandler, "foreground", BROADCAST_FG_TIMEOUT, false); //BROADCAST_BG_TIMEOUT 后台 60s mBgBroadcastQueue = new BroadcastQueue(this, mHandler, "background", BROADCAST_BG_TIMEOUT, true); mBroadcastQueues[0] = mFgBroadcastQueue; mBroadcastQueues[1] = mBgBroadcastQueue; //略 }
BroadcastQueue.java
sendPendingBroadcastsLocked()
public boolean sendPendingBroadcastsLocked(ProcessRecord app) { boolean didSomething = false; final BroadcastRecord br = mPendingBroadcast; //之前存储的是后台BroadcastQueue,(之前备注了60s超时ANR处) if (br != null && br.curApp.pid > 0 && br.curApp.pid == app.pid) { if (br.curApp != app) { return false; } try { mPendingBroadcast = null; //满足条件后就执行这个,处理广播 processCurBroadcastLocked(br, app, false); didSomething = true; } catch (Exception e) { logBroadcastReceiverDiscardLocked(br); finishReceiverLocked(br, br.resultCode, br.resultData, br.resultExtras, br.resultAbort, false); scheduleBroadcastsLocked(); br.state = BroadcastRecord.IDLE; throw new RuntimeException(e.getMessage()); } } return didSomething; }
processCurBroadcastLocked()
这里也不是真正处理广播的,最终又调用了ActivityThread0
private final void processCurBroadcastLocked(BroadcastRecord r, ProcessRecord app, boolean skipOomAdj) throws RemoteException { if (app.thread == null) { throw new RemoteException(); } if (app.inFullBackup) { skipReceiverLocked(r); return; } r.receiver = app.thread.asBinder(); r.curApp = app; app.curReceivers.add(r); app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER); mService.updateLruProcessLocked(app, false, null); if (!skipOomAdj) { mService.updateOomAdjLocked(); } r.intent.setComponent(r.curComponent); boolean started = false; try { mService.notifyPackageUse(r.intent.getComponent().getPackageName(), PackageManager.NOTIFY_PACKAGE_USE_BROADCAST_RECEIVER); //看这里ActivityThread.ApplicationThread.scheduleReceiver app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver, mService.compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo), r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId, app.repProcState); started = true; } finally { if (!started) { r.receiver = null; r.curApp = null; app.curReceivers.remove(r); } } }
ActivityThread.java
是内部ApplicationThread的方法
public final void scheduleReceiver(Intent intent, ActivityInfo info, CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras, boolean sync, int sendingUser, int processState) { updateProcessState(processState, false); ReceiverData r = new ReceiverData(intent, resultCode, data, extras, sync, false, mAppThread.asBinder(), sendingUser); r.info = info; r.compatInfo = compatInfo; //发送H.RECEIVER sendMessage(H.RECEIVER, r); }
handleMessage()
public void handleMessage(Message msg) { //略 case RECEIVER: handleReceiver((ReceiverData)msg.obj); break; //略 }
handleReceiver()
这里才真正发送广播给接收者:receiver.onReceive()
private void handleReceiver(ReceiverData data) { unscheduleGcIdler(); String component = data.intent.getComponent().getClassName(); LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); IActivityManager mgr = ActivityManager.getService(); Application app; BroadcastReceiver receiver; ContextImpl context; try { //获取Application,之前makeApplication过 app = packageInfo.makeApplication(false, mInstrumentation); context = (ContextImpl) app.getBaseContext(); if (data.info.splitName != null) { context = (ContextImpl) context.createContextForSplit(data.info.splitName); } java.lang.ClassLoader cl = context.getClassLoader(); data.intent.setExtrasClassLoader(cl); data.intent.prepareToEnterProcess(); data.setExtrasClassLoader(cl); //获取广播接收者 receiver = packageInfo.getAppFactory() .instantiateReceiver(cl, data.info.name, data.intent); } catch (Exception e) { data.sendFinished(mgr); throw new RuntimeException( "Unable to instantiate receiver " + component + ": " + e.toString(), e); } try { sCurrentBroadcastIntent.set(data.intent); receiver.setPendingResult(data); //调用onReceive() receiver.onReceive(context.getReceiverRestrictedContext(), data.intent); } catch (Exception e) { data.sendFinished(mgr); if (!mInstrumentation.onException(receiver, e)) { throw new RuntimeException( "Unable to start receiver " + component + ": " + e.toString(), e); } } finally { sCurrentBroadcastIntent.set(null); } if (receiver.getPendingResult() != null) { data.finish(); } }
参考文章