以前看過 Activity 的啓動過程,也看過 Service 啓動過程,今天又從新對廣播的發送和接收過程作一個源碼的瞭解和查看。java
MyBroadcastReceiver mBroadcastReceiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.example.qq");
registerReceiver(mBroadcastReceiver, filter);
複製代碼
咱們一般會自定義一個類 MyBroadcastReceiver extends BroadcastReceiver
.android
跟隨 registerReceiver
咱們走到第二個步驟:app
@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());
}
複製代碼
最終會執行到 registerReceiverInternal()
這個方法,緊接着到第三個步驟:async
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId, IntentFilter filter, String broadcastPermission, Handler scheduler, Context context) {
IIntentReceiver rd = null;//這個IItentReceiver 是一個aidl ,一個Binder
if (receiver != null) {
if (mPackageInfo != null && context != null) {
//這個爲null, 由於前面咱們傳的是null,獲取主線程的一個handler
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 {
//這裏咱們仔細查看,這裏對比咱們平時寫的Aidl
final Intent intent = ActivityManagerNative.getDefault().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName,
rd, filter, broadcastPermission, userId);
if (intent != null) {
intent.setExtrasClassLoader(getClassLoader());
intent.prepareToEnterProcess();
}
return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
複製代碼
對於 :ide
final Intent intent = ActivityManagerNative.getDefault().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName,
rd, filter, broadcastPermission, userId);
複製代碼
ActivityManagerNative.getDefault()
獲取到一個 IActivityManager
對象,此時我發現,我進入一個類名爲: ActivityManagerNative
的一個類中。oop
這裏補充 IActivityManager
,它是一個 aidl
文件,以下:post
public interface IActivityManager extends IInterface {
....
}
複製代碼
這時讓我想起咱們之前寫 aidl 的示例時,系統自動幫咱們生成的文件,下面咱們來對比一下,能夠加深對 aidl 的理解:ui
自動生成的aidl文件 咱們建立一個 IMyAidl.aidl
文件,編譯系統會自動生成大體以下:this
public interface IMyAidl extends android.os.IInterface{
public static abstract class Stub extends android.os.Binder implements xx.IMyAidl{
public Stub(){
this.attachInterface(this, DESCRIPTOR);
}
public static com.example.service.bean.IMyAidl asInterface(android.os.IBinder obj) {
xxx...
return new com.example.service.bean.IMyAidl.Stub.Proxy(obj);
}
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
case TRANSACTION_addPerson: {//其中一個方法
data.enforceInterface(DESCRIPTOR);
com.example.service.bean.Person _arg0;
if ((0 != data.readInt())) {
_arg0 = com.example.service.bean.Person.CREATOR.createFromParcel(data);
} else {
_arg0 = null;
}
this.addPerson(_arg0);
reply.writeNoException();
return true;
}
}
}
private static class Proxy implements xx.IMyAidl {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public void addPerson(com.example.service.bean.Person person) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((person != null)) {
_data.writeInt(1);
person.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
//調用遠程binder,transact
mRemote.transact(Stub.TRANSACTION_addPerson, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
}
static final int TRANSACTION_addPerson = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
複製代碼
其中咱們最主要關心的是 Stub
和 Proxy
.那麼類比下 ActivityManagerNative
類(我簡化了一下):spa
public abstract class ActivityManagerNative extends Binder implements IActivityManager{
class ActivityManagerProxy implements IActivityManager{
public ActivityManagerProxy(IBinder remote) {
mRemote = remote;
}
}
}
複製代碼
你會發現這與系統幫咱們自動生成文件的結構有殊途同歸之處,那麼在這裏:
ActivityManagerNative
------ 對應的就是 Stub
ActivityManagerProxy
------- 對應的就是 Proxy
那麼真正實現 ActivityManagerNative
又是誰呢,其實就是 ActivityManagerService
, 可看到:
public final class ActivityManagerService extends ActivityManagerNative ...{
...
}
複製代碼
這樣的話,咱們回到以前的那個步驟:
final Intent intent = ActivityManagerNative.getDefault().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName,
rd, filter, broadcastPermission, userId);
複製代碼
這裏咱們就知道了 這裏調用 ActivityManagerNative.getDefault().registerReceiver
其實就是調用 ActivityManagerService.registerReceiver()
方法。
還有一個補充的是
mMainThread.getApplicationThread()
實際上對應的是ApplicationThread
這個方法有點長,不過不要緊,分塊看就行:
public Intent registerReceiver(IApplicationThread caller, String callerPackage, IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
enforceNotIsolatedCaller("registerReceiver");
ArrayList<Intent> stickyIntents = null;
ProcessRecord callerApp = null;
int callingUid;
int callingPid;
synchronized(this) {
//這個確定不爲null
if (caller != null) {
//表示啓動app的進程信息保存在ProcessRecord類型的對象中
callerApp = getRecordForAppLocked(caller);
if (callerApp == null) {
throw new SecurityException(
"Unable to find app for caller " + caller
+ " (pid=" + Binder.getCallingPid()
+ ") when registering receiver " + receiver);
}
....
} else {
...
}
userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
....
// Collect stickies of users
int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
//遍歷 action
while (actions.hasNext()) {
String action = actions.next();
for (int id : userIds) {
ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
if (stickies != null) {
ArrayList<Intent> intents = stickies.get(action);
if (intents != null) {
if (stickyIntents == null) {
stickyIntents = new ArrayList<Intent>();
}
stickyIntents.addAll(intents);
}
}
}
}
}
ArrayList<Intent> allSticky = null;
if (stickyIntents != null) {
final ContentResolver resolver = mContext.getContentResolver();
// Look for any matching sticky broadcasts...
for (int i = 0, N = stickyIntents.size(); i < N; i++) {
Intent intent = stickyIntents.get(i);
// If intent has scheme "content", it will need to acccess
// provider that needs to lock mProviderMap in ActivityThread
// and also it may need to wait application response, so we
// cannot lock ActivityManagerService here.
if (filter.match(resolver, intent, true, TAG) >= 0) {
if (allSticky == null) {
allSticky = new ArrayList<Intent>();
}
allSticky.add(intent);
}
}
}
// The first sticky in the list is returned directly back to the client.
Intent sticky = allSticky != null ? allSticky.get(0) : null;
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
if (receiver == null) {
return sticky;
}
synchronized (this) {
...
//獲取接收者的一個集合 ReceiverList
ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {
rl = new ReceiverList(this, callerApp, callingPid, callingUid,
userId, receiver);
if (rl.app != null) {
rl.app.receivers.add(rl);
} else {
try {
receiver.asBinder().linkToDeath(rl, 0);
} catch (RemoteException e) {
return sticky;
}
rl.linkedToDeath = true;
}
mRegisteredReceivers.put(receiver.asBinder(), rl);
}
...
//IntentFilter 相關的
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
permission, callingUid, userId);
rl.add(bf);
if (!bf.debugCheck()) {
Slog.w(TAG, "==> For Dynamic broadcast");
}
//最後添加到了mReceiverResolver 中,最後發送廣播也是從這裏面去取
///**
//* Keeps track of all IIntentReceivers that have been registered for broadcasts.
// * Hash keys are the receiver IBinder, hash value is a ReceiverList.
//*/
//final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
mReceiverResolver.addFilter(bf);
// Enqueue broadcasts for all existing stickies that match
// this filter.
if (allSticky != null) {
ArrayList receivers = new ArrayList();
receivers.add(bf);
final int stickyCount = allSticky.size();
for (int i = 0; i < stickyCount; i++) {
Intent intent = allSticky.get(i);
//獲得一個接收此廣播的隊列 BroadcastQueue
BroadcastQueue queue = broadcastQueueForIntent(intent);
//廣播的信息封裝在一個BroadcastRecord 對象中
BroadcastRecord r = new BroadcastRecord(queue, intent, null,
null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
null, 0, null, null, false, true, true, -1);
// 這裏能夠認爲是一個入隊操做,就像Handler 中的 Message中同樣
queue.enqueueParallelBroadcastLocked(r);
//調用 scheduleBroadcastsLocked
queue. scheduleBroadcastsLocked();
}
}
return sticky;
}
}
複製代碼
Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction("com.example.qq");
sendBroadcast(intent);
複製代碼
@Override
public void sendBroadcast(Intent intent) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
intent.prepareToLeaveProcess(this);
ActivityManagerNative.getDefault().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();
}
}
複製代碼
這裏咱們就知道 ActivityManagerNative.getDefault()
實際上能夠認爲是 ActivityManagerService
,調用 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) {
enforceNotIsolatedCaller("broadcastIntent");
synchronized(this) {
intent = verifyBroadcastLocked(intent);
final ProcessRecord callerApp = getRecordForAppLocked(caller);
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
//到這裏
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;
}
}
複製代碼
這個裏面方法挺長的
....
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, resolvedType,
requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
resultData, resultExtras, ordered, sticky, false, userId);
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
+ ": prev had " + queue.mOrderedBroadcasts.size());
if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
"Enqueueing broadcast " + r.intent.getAction());
boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
if (!replaced) {
queue.enqueueOrderedBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
....
複製代碼
public void scheduleBroadcastsLocked() {
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["
+ mQueueName + "]: current="
+ mBroadcastsScheduled);
if (mBroadcastsScheduled) {
return;
}
//這裏發送了一條消息
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}
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");
processNextBroadcast(true);
} break;
...
複製代碼
這個方法也比較長,挑一些重點的看下:
final void processNextBroadcast(boolean fromMsg) {
...
// First, deliver any non-serialized broadcasts right away.
//這個表示對無序廣播的處理
while (mParallelBroadcasts.size() > 0) {
r = mParallelBroadcasts.remove(0);
r.dispatchTime = SystemClock.uptimeMillis();
r.dispatchClockTime = System.currentTimeMillis();
final int N = r.receivers.size();
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
+ mQueueName + "] " + r);
for (int i=0; i<N; i++) {
//取出一個接收者target
Object target = r.receivers.get(i);
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"Delivering non-ordered on [" + mQueueName + "] to registered "
+ target + ": " + r);
//又調用 deliverToRegisteredReceiverLocked
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
}
addBroadcastToHistoryLocked(r);
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
+ mQueueName + "] " + r);
}
}
複製代碼
private void deliverToRegisteredReceiverLocked(BroadcastRecord r, BroadcastFilter filter, boolean ordered, int index) {
//根據上面所傳的ordered 爲false 表示無序廣播
....
if (ordered) {//這個表示有序廣播
r.receiver = filter.receiverList.receiver.asBinder();
r.curFilter = filter;
filter.receiverList.curBroadcast = r;
r.state = BroadcastRecord.CALL_IN_RECEIVE;
if (filter.receiverList.app != null) {
// Bump hosting application to no longer be in background
// scheduling class. Note that we can't do that if there
// isn't an app... but we can only be in that case for
// things that directly call the IActivityManager API, which
// are already core system stuff so don't matter for this.
r.curApp = filter.receiverList.app;
filter.receiverList.app.curReceiver = r;
mService.updateOomAdjLocked(r.curApp);
}
}
try {
//關於isFullBackup Process is currently hosting a backup agent for backup or restore
//public boolean inFullBackup;默認是false
if (filter.receiverList.app != null && filter.receiverList.app.inFullBackup) {
// Skip delivery if full backup in progress
// If it's an ordered broadcast, we need to continue to the next receiver.
if (ordered) {
skipReceiverLocked(r);
}
} else {
//到這裏
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.userId);
}
if (ordered) {
r.state = BroadcastRecord.CALL_DONE_RECEIVE;
}
} catch (RemoteException e) {
....
}
複製代碼
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
// Send the intent to the receiver asynchronously using one-way binder calls.
....
if (app != null) {
if (app.thread != null) {
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.repProcState);
}
....
}
複製代碼
app.thread
是 ApplicationThread
, 此時迴歸到了客戶端進程,ApplicationThread
中了
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);
}
複製代碼
這裏調用了 IIntentReceiver#performReceive
方法, 其中 IIntentReceiver
是一個 aidl ,以下: /framworkds/base/core/java/android/content/IIntentReceiver.aidl
/** * System private API for dispatching intent broadcasts. This is given to the * activity manager as part of registering for an intent broadcasts, and is * called when it receives intents. * * {@hide} */
oneway interface IIntentReceiver {
void performReceive(in Intent intent, int resultCode, String data, in Bundle extras, boolean ordered, boolean sticky);
}
複製代碼
既然是 aidl 確定有最終實現者,全局搜索發現:
InnerReceiver
是最終實現者,是ReceiverDispatcher
的一個靜態內部類,在 LoadedApk.java
文件中
LoadedApk#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;
}
//這裏是最終執行的方法 performReceive
@Override
public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
final LoadedApk.ReceiverDispatcher rd;
if (intent == null) {
Log.wtf(TAG, "Null intent received");
rd = null;
} else {
rd = mDispatcher.get();
}
...
if (rd != null) {
//不爲null 執行到這裏
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky, sendingUser);
} else {
// The activity manager dispatched a broadcast to a registered
// receiver in this process, but before it could be delivered the
// receiver was unregistered. Acknowledge the broadcast on its
// behalf so that the system's broadcast sequence can continue.
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing broadcast to unregistered receiver");
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
if (extras != null) {
extras.setAllowFds(false);
}
mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
}
複製代碼
public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
//將信息封裝到Args 中
final Args args = new Args(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
if (intent == null) {
Log.wtf(TAG, "Null intent received");
} else {
if (ActivityThread.DEBUG_BROADCAST) {
int seq = intent.getIntExtra("seq", -1);
Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()
+ " seq=" + seq + " to " + mReceiver);
}
}
//這裏 IActivityThread 一個Handler 類型。post了一條runnable,
if (intent == null || !mActivityThread.post(args)) {
if (mRegistered && ordered) {
IActivityManager mgr = ActivityManagerNative.getDefault();
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing sync broadcast to " + mReceiver);
args.sendFinished(mgr);
}
}
}
複製代碼
這裏補充下 : mActivityThread
賦值是在構造方法中賦值的:
ReceiverDispatcher(BroadcastReceiver receiver, Context context,
Handler activityThread, Instrumentation instrumentation,
boolean registered) {
...
mIIntentReceiver = new InnerReceiver(this, !registered);
.... 這裏也能猜到 是ActivityThread 中的那個H
mActivityThread = activityThread;
...
}
複製代碼
這裏就能夠看 Args
,一個 Runnable
, 看下 run
方法:
final class Args extends BroadcastReceiver.PendingResult implements Runnable {
public void run() {
final BroadcastReceiver receiver = mReceiver;
final boolean ordered = mOrdered;
if (ActivityThread.DEBUG_BROADCAST) {
int seq = mCurIntent.getIntExtra("seq", -1);
Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
+ " seq=" + seq + " to " + mReceiver);
Slog.i(ActivityThread.TAG, " mRegistered=" + mRegistered
+ " mOrderedHint=" + ordered);
}
final IActivityManager mgr = ActivityManagerNative.getDefault();
final Intent intent = mCurIntent;
if (intent == null) {
Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched);
}
mCurIntent = null;
mDispatched = true;
...
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
try {
//獲取receiver的類加載類加載
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
intent.prepareToEnterProcess();
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
//這裏回調receiver 的onReceive 方法
receiver.onReceive(mContext, intent);
} catch (Exception e) {
...
}
...
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
複製代碼
這樣咱們就能夠在 sendBroadcast
時,在 Receiver
方法中收到相應的回調了,完畢。