前面我們分析了Android應(yīng)用程序注冊(cè)廣播接收器的過(guò)程,這個(gè)過(guò)程只完成了萬(wàn)里長(zhǎng)征的第一步,接下來(lái)它還要等待ActivityManagerService將廣播分發(fā)過(guò)來(lái)。ActivityManagerService是如何得到廣播并把它分發(fā)出去的呢?這就是本文要介紹的廣播發(fā)送過(guò)程了。
廣播的發(fā)送過(guò)程比廣播接收器的注冊(cè)過(guò)程要復(fù)雜得多了,不過(guò)這個(gè)過(guò)程仍然是以ActivityManagerService為中心。廣播的發(fā)送者將廣播發(fā)送到ActivityManagerService,ActivityManagerService接收到這個(gè)廣播以后,就會(huì)在自己的注冊(cè)中心查看有哪些廣播接收器訂閱了該廣播,然后把這個(gè)廣播逐一發(fā)送到這些廣播接收器中,但是ActivityManagerService并不等待廣播接收器處理這些廣播就返回了,因此,廣播的發(fā)送和處理是異步的。概括來(lái)說(shuō),廣播的發(fā)送路徑就是從發(fā)送者到ActivityManagerService,再?gòu)腁ctivityManagerService到接收者,這中間的兩個(gè)過(guò)程都是通過(guò)Binder進(jìn)程間通信機(jī)制來(lái)完成的,因此,希望讀者在繼續(xù)閱讀本文之前,對(duì)Android系統(tǒng)的Binder進(jìn)程間通信機(jī)制有所了解,具體可以參考Android進(jìn)程間通信(IPC)機(jī)制Binder簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃一文。
本文繼續(xù)以Android系統(tǒng)中的廣播(Broadcast)機(jī)制簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃一文中所開(kāi)發(fā)的應(yīng)用程序?yàn)槔樱⑶医Y(jié)合上文Android應(yīng)用程序注冊(cè)廣播接收器(registerReceiver)的過(guò)程分析的內(nèi)容,一起來(lái)分析Android應(yīng)用程序發(fā)送廣播的過(guò)程。
回顧一下Android系統(tǒng)中的廣播(Broadcast)機(jī)制簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃一文中所開(kāi)發(fā)的應(yīng)用程序的組織架構(gòu),MainActivity向ActivityManagerService注冊(cè)了一個(gè)CounterService.BROADCAST_COUNTER_ACTION類型的計(jì)數(shù)器服務(wù)廣播接收器,計(jì)數(shù)器服務(wù)CounterService在后臺(tái)線程中啟動(dòng)了一個(gè)異步任務(wù)(AsyncTask),這個(gè)異步任務(wù)負(fù)責(zé)不斷地增加計(jì)數(shù),并且不斷地將當(dāng)前計(jì)數(shù)值通過(guò)廣播的形式發(fā)送出去,以便MainActivity可以將當(dāng)前計(jì)數(shù)值在應(yīng)用程序的界面線程中顯示出來(lái)。
計(jì)數(shù)器服務(wù)CounterService發(fā)送廣播的代碼如下所示:
public class CounterService extends Service implements ICounterService {
......
public void startCounter(int initVal) {
AsyncTask<Integer, Integer, Integer> task = new AsyncTask<Integer, Integer, Integer>() {
@Override
protected Integer doInBackground(Integer... vals) {
......
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
int counter = values[0];
Intent intent = new Intent(BROADCAST_COUNTER_ACTION);
intent.putExtra(COUNTER_VALUE, counter);
sendBroadcast(intent);
}
@Override
protected void onPostExecute(Integer val) {
......
}
};
task.execute(0);
}
......
}
在onProgressUpdate函數(shù)中,創(chuàng)建了一個(gè)BROADCAST_COUNTER_ACTION類型的Intent,并且在這里個(gè)Intent中附加上當(dāng)前的計(jì)數(shù)器值,然后通過(guò)CounterService類的成員函數(shù)sendBroadcast將這個(gè)Intent發(fā)送出去。CounterService類繼承了Service類,Service類又繼承了ContextWrapper類,成員函數(shù)sendBroadcast就是從ContextWrapper類繼承下來(lái)的,因此,我們就從ContextWrapper類的sendBroadcast函數(shù)開(kāi)始,分析廣播發(fā)送的過(guò)程。
在繼承分析廣播的發(fā)送過(guò)程前,我們先來(lái)看一下廣播發(fā)送過(guò)程的序列圖,然后按照這個(gè)序圖中的步驟來(lái)一步一步分析整個(gè)過(guò)程。

點(diǎn)擊查看大圖
Step 1. ContextWrapper.sendBroadcast
這個(gè)函數(shù)定義在frameworks/base/core/java/android/content/ContextWrapper.java文件中:
public class ContextWrapper extends Context {
Context mBase;
......
@Override
public void sendBroadcast(Intent intent) {
mBase.sendBroadcast(intent);
}
......
}
這里的成員變量mBase是一個(gè)ContextImpl實(shí)例,這里只簡(jiǎn)單地調(diào)用ContextImpl.sendBroadcast進(jìn)一行操作。
Step 2. ContextImpl.sendBroadcast
這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ContextImpl.java文件中:
class ContextImpl extends Context {
......
@Override
public void sendBroadcast(Intent intent) {
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, null, false, false);
} catch (RemoteException e) {
}
}
......
}
這里的resolvedType表示這個(gè)Intent的MIME類型,我們沒(méi)有設(shè)置這個(gè)Intent的MIME類型,因此,這里的resolvedType為null。接下來(lái)就調(diào)用ActivityManagerService的遠(yuǎn)程接口ActivityManagerProxy把這個(gè)廣播發(fā)送給ActivityManagerService了。
Step 3. ActivityManagerProxy.broadcastIntent
這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:
class ActivityManagerProxy implements IActivityManager
{
......
public int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle map,
String requiredPermission, boolean serialized,
boolean sticky) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo != null ? resultTo.asBinder() : null);
data.writeInt(resultCode);
data.writeString(resultData);
data.writeBundle(map);
data.writeString(requiredPermission);
data.writeInt(serialized ? 1 : 0);
data.writeInt(sticky ? 1 : 0);
mRemote.transact(BROADCAST_INTENT_TRANSACTION, data, reply, 0);
reply.readException();
int res = reply.readInt();
reply.recycle();
data.recycle();
return res;
}
......
}
這里的實(shí)現(xiàn)比較簡(jiǎn)單,把要傳遞的參數(shù)封裝好,然后通過(guò)Binder驅(qū)動(dòng)程序進(jìn)入到ActivityManagerService的broadcastIntent函數(shù)中。
Step 4. ctivityManagerService.broadcastIntent
這個(gè)函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
......
public final int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle map,
String requiredPermission, boolean serialized, boolean sticky) {
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, map, requiredPermission, serialized,
sticky, callingPid, callingUid);
Binder.restoreCallingIdentity(origId);
return res;
}
}
......
}
這里調(diào)用broadcastIntentLocked函數(shù)來(lái)進(jìn)一步處理。
Step 5. ActivityManagerService.broadcastIntentLocked
這個(gè)函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
......
private final int broadcastIntentLocked(ProcessRecord callerApp,
String callerPackage, Intent intent, String resolvedType,
IIntentReceiver resultTo, int resultCode, String resultData,
Bundle map, String requiredPermission,
boolean ordered, boolean sticky, int callingPid, int callingUid) {
intent = new Intent(intent);
......
// Figure out who all will receive this broadcast.
List receivers = null;
List<BroadcastFilter> registeredReceivers = null;
try {
if (intent.getComponent() != null) {
......
} else {
......
registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
}
} catch (RemoteException ex) {
......
}
final boolean replacePending =
(intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
if (!ordered && NR > 0) {
// If we are not serializing this broadcast, then send the
// registered receivers separately so they don't wait for the
// components to be launched.
BroadcastRecord r = new BroadcastRecord(intent, callerApp,
callerPackage, callingPid, callingUid, requiredPermission,
registeredReceivers, resultTo, resultCode, resultData, map,
ordered, sticky, false);
......
boolean replaced = false;
if (replacePending) {
for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
......
mParallelBroadcasts.set(i, r);
replaced = true;
break;
}
}
}
if (!replaced) {
mParallelBroadcasts.add(r);
scheduleBroadcastsLocked();
}
registeredReceivers = null;
NR = 0;
}
......
}
......
}
這個(gè)函數(shù)首先是根據(jù)intent找出相應(yīng)的廣播接收器:
// Figure out who all will receive this broadcast.
List receivers = null;
List<BroadcastFilter> registeredReceivers = null;
try {
if (intent.getComponent() != null) {
......
} else {
......
registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
}
} catch (RemoteException ex) {
......
}
回憶一下前面一篇文章
Android應(yīng)用程序注冊(cè)廣播接收器(registerReceiver)的過(guò)程分析中的Step 6(ActivityManagerService.registerReceiver)中,我們將一個(gè)filter類型為BROADCAST_COUNTER_ACTION類型的BroadcastFilter實(shí)例保存在了ActivityManagerService的成員變量mReceiverResolver中,這個(gè)BroadcastFilter實(shí)例包含了我們所注冊(cè)的廣播接收器,這里就通過(guò)mReceiverResolver.queryIntent函數(shù)將這個(gè)BroadcastFilter實(shí)例取回來(lái)。由于注冊(cè)一個(gè)廣播類型的接收器可能有多個(gè),所以這里把所有符合條件的的BroadcastFilter實(shí)例放在一個(gè)List中,然后返回來(lái)。在我們這個(gè)場(chǎng)景中,這個(gè)List就只有一個(gè)BroadcastFilter實(shí)例了,就是MainActivity注冊(cè)的那個(gè)廣播接收器。
繼續(xù)往下看:
final boolean replacePending =
(intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
這里是查看一下這個(gè)intent的Intent.FLAG_RECEIVER_REPLACE_PENDING位有沒(méi)有設(shè)置,如果設(shè)置了的話,ActivityManagerService就會(huì)在當(dāng)前的系統(tǒng)中查看有沒(méi)有相同的intent還未被處理,如果有的話,就有當(dāng)前這個(gè)新的intent來(lái)替換舊的intent。這里,我們沒(méi)有設(shè)置intent的Intent.FLAG_RECEIVER_REPLACE_PENDING位,因此,這里的replacePending變量為false。
再接著往下看:
int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
if (!ordered && NR > 0) {
// If we are not serializing this broadcast, then send the
// registered receivers separately so they don't wait for the
// components to be launched.
BroadcastRecord r = new BroadcastRecord(intent, callerApp,
callerPackage, callingPid, callingUid, requiredPermission,
registeredReceivers, resultTo, resultCode, resultData, map,
ordered, sticky, false);
......
boolean replaced = false;
if (replacePending) {
for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
......
mParallelBroadcasts.set(i, r);
replaced = true;
break;
}
}
}
if (!replaced) {
mParallelBroadcasts.add(r);
scheduleBroadcastsLocked();
}
registeredReceivers = null;
NR = 0;
}
前面我們說(shuō)到,這里得到的列表registeredReceivers的大小為1,且傳進(jìn)來(lái)的參數(shù)ordered為false,表示要將這個(gè)廣播發(fā)送給所有注冊(cè)了BROADCAST_COUNTER_ACTION類型廣播的接收器,因此,會(huì)執(zhí)行下面的if語(yǔ)句。這個(gè)if語(yǔ)句首先創(chuàng)建一個(gè)廣播記錄塊BroadcastRecord,里面記錄了這個(gè)廣播是由誰(shuí)發(fā)出的以及要發(fā)給誰(shuí)等相關(guān)信息。由于前面得到的replacePending變量為false,因此,不會(huì)執(zhí)行接下來(lái)的if語(yǔ)句,即不會(huì)檢查系統(tǒng)中是否有相同類型的未處理的廣播。
這樣,這里得到的replaced變量的值也為false,于是,就會(huì)把這個(gè)廣播記錄塊r放在ActivityManagerService的成員變量mParcelBroadcasts中,等待進(jìn)一步處理;進(jìn)一步處理的操作由函數(shù)scheduleBroadcastsLocked進(jìn)行。
Step 6. ActivityManagerService.scheduleBroadcastsLocked
這個(gè)函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
......
private final void scheduleBroadcastsLocked() {
......
if (mBroadcastsScheduled) {
return;
}
mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
mBroadcastsScheduled = true;
}
......
}
這里的mBroadcastsScheduled表示ActivityManagerService當(dāng)前是不是正在處理其它廣播,如果是的話,這里就先不處理直接返回了,保證所有廣播串行處理。
注意這里處理廣播的方式,它是通過(guò)消息循環(huán)來(lái)處理,每當(dāng)ActivityManagerService接收到一個(gè)廣播時(shí),它就把這個(gè)廣播放進(jìn)自己的消息隊(duì)列去就完事了,根本不管這個(gè)廣播后續(xù)是處理的,因此,這里我們可以看出廣播的發(fā)送和處理是異步的。
這里的成員變量mHandler是一個(gè)在ActivityManagerService內(nèi)部定義的Handler類變量,通過(guò)它的sendEmptyMessage函數(shù)把一個(gè)類型為BROADCAST_INTENT_MSG的空消息放進(jìn)ActivityManagerService的消息隊(duì)列中去。這里的空消息是指這個(gè)消息除了有類型信息之外,沒(méi)有任何其它額外的信息,因?yàn)榍懊嬉呀?jīng)把要處理的廣播信息都保存在mParcelBroadcasts中了,等處理這個(gè)消息時(shí),從mParcelBroadcasts就可以讀回相關(guān)的廣播信息了,因此,這里不需要把廣播信息再放在消息內(nèi)容中。
Step 7. Handler.sendEmptyMessage
這個(gè)自定義的Handler類實(shí)現(xiàn)在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中,它是ActivityManagerService的內(nèi)部類,調(diào)用了它的sendEmptyMessage函數(shù)來(lái)把一個(gè)消息放到消息隊(duì)列后,一會(huì)就會(huì)調(diào)用它的handleMessage函數(shù)來(lái)真正處理這個(gè)消息:
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
......
final Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
......
case BROADCAST_INTENT_MSG: {
......
processNextBroadcast(true);
} break;
......
}
}
}
......
}
這里又調(diào)用了ActivityManagerService的processNextBroadcast函數(shù)來(lái)處理下一個(gè)未處理的廣播。
Step 8. ActivityManagerService.processNextBroadcast
這個(gè)函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
......
private final void processNextBroadcast(boolean fromMsg) {
synchronized(this) {
BroadcastRecord r;
......
if (fromMsg) {
mBroadcastsScheduled = false;
}
// First, deliver any non-serialized broadcasts right away.
while (mParallelBroadcasts.size() > 0) {
r = mParallelBroadcasts.remove(0);
......
final int N = r.receivers.size();
......
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
......
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
}
addBroadcastToHistoryLocked(r);
......
}
......
}
}
......
}
這里傳進(jìn)來(lái)的參數(shù)fromMsg為true,于是把mBroadcastScheduled重新設(shè)為false,這樣,下一個(gè)廣播就能進(jìn)入到消息隊(duì)列中進(jìn)行處理了。前面我們?cè)赟tep 5中,把一個(gè)廣播記錄塊BroadcastRecord放在了mParallelBroadcasts中,因此,這里就把它取出來(lái)進(jìn)行處理了。廣播記錄塊BroadcastRecord的receivers列表中包含了要接收這個(gè)廣播的目標(biāo)列表,即前面我們注冊(cè)的廣播接收器,用BroadcastFilter來(lái)表示,這里while循環(huán)中的for循環(huán)就是把這個(gè)廣播發(fā)送給每一個(gè)訂閱了該廣播的接收器了,通過(guò)deliverToRegisteredReceiverLocked函數(shù)執(zhí)行。
Step 9. ActivityManagerService.deliverToRegisteredReceiverLocked
這個(gè)函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
......
private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
BroadcastFilter filter, boolean ordered) {
boolean skip = false;
if (filter.requiredPermission != null) {
......
}
if (r.requiredPermission != null) {
......
}
if (!skip) {
// If this is not being sent as an ordered broadcast, then we
// don't want to touch the fields that keep track of the current
// state of ordered broadcasts.
if (ordered) {
......
}
try {
......
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode,
r.resultData, r.resultExtras, r.ordered, r.initialSticky);
......
} catch (RemoteException e) {
......
}
}
}
......
}
函數(shù)首先是檢查一下廣播發(fā)送和接收的權(quán)限,在我們分析的這個(gè)場(chǎng)景中,沒(méi)有設(shè)置權(quán)限,因此,這個(gè)權(quán)限檢查就跳過(guò)了,這里得到的skip為false,于是進(jìn)入下面的if語(yǔ)句中。由于上面?zhèn)鲿r(shí)來(lái)的ordered參數(shù)為false,因此,直接就調(diào)用performReceiveLocked函數(shù)來(lái)進(jìn)一步執(zhí)行廣播發(fā)送的操作了。
Step 10. ActivityManagerService.performReceiveLocked
這個(gè)函數(shù)定義在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
......
static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky) throws RemoteException {
// Send the intent to the receiver asynchronously using one-way binder calls.
if (app != null && app.thread != null) {
// If we have an app thread, do the call through that so it is
// correctly ordered with other one-way calls.
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky);
} else {
......
}
}
......
}
注意,這里傳進(jìn)來(lái)的參數(shù)app是注冊(cè)廣播接收器的Activity所在的進(jìn)程記錄塊,在我們分析的這個(gè)場(chǎng)景中,由于是MainActivity調(diào)用registerReceiver函數(shù)來(lái)注冊(cè)這個(gè)廣播接收器的,因此,參數(shù)app所代表的ProcessRecord就是MainActivity所在的進(jìn)程記錄塊了;而參數(shù)receiver也是注冊(cè)廣播接收器時(shí)傳給ActivityManagerService的一個(gè)Binder對(duì)象,它的類型是IIntentReceiver,具體可以參考上一篇文章
Android應(yīng)用程序注冊(cè)廣播接收器(registerReceiver)的過(guò)程分析中的Step 2。
MainActivity在注冊(cè)廣播接收器時(shí),已經(jīng)把自己的ProcessRecord記錄下來(lái)了,所以這里的參數(shù)app和app.thread均不為null,于是,ActivityManagerService就調(diào)用app.thread.scheduleRegisteredReceiver函數(shù)來(lái)把這個(gè)廣播分發(fā)給MainActivity了。這里的app.thread是一個(gè)Binder遠(yuǎn)程對(duì)象,它的類型是ApplicationThreadProxy,我們?cè)谇懊娼榻B應(yīng)用程序的Activity啟動(dòng)過(guò)程時(shí),已經(jīng)多次看到了,具體可以參考主題Android應(yīng)用程序的Activity啟動(dòng)過(guò)程簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃。
Step 11. ApplicationThreadProxy.scheduleRegisteredReceiver
這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:
class ApplicationThreadProxy implements IApplicationThread {
......
public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
int resultCode, String dataStr, Bundle extras, boolean ordered, boolean sticky)
throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(receiver.asBinder());
intent.writeToParcel(data, 0);
data.writeInt(resultCode);
data.writeString(dataStr);
data.writeBundle(extras);
data.writeInt(ordered ? 1 : 0);
data.writeInt(sticky ? 1 : 0);
mRemote.transact(SCHEDULE_REGISTERED_RECEIVER_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
......
}
這里通過(guò)Binder驅(qū)動(dòng)程序就進(jìn)入到ApplicationThread.scheduleRegisteredReceiver函數(shù)去了。ApplicationThread是ActivityThread的一個(gè)內(nèi)部類,具體可以參考Activity啟動(dòng)主題
Android應(yīng)用程序的Activity啟動(dòng)過(guò)程簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃。
Step 12. ApplicaitonThread.scheduleRegisteredReceiver
這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/ActivityThread.java文件中:
public final class ActivityThread {
......
private final class ApplicationThread extends ApplicationThreadNative {
......
// 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) throws RemoteException {
receiver.performReceive(intent, resultCode, dataStr, extras, ordered, sticky);
}
......
}
......
}
這里的receiver是在前面一篇文章
Android應(yīng)用程序注冊(cè)廣播接收器(registerReceiver)的過(guò)程分析中的Step 4中創(chuàng)建的,它的具體類型是LoadedApk.ReceiverDispatcher.InnerReceiver,即定義在LoadedApk類的內(nèi)部類ReceiverDispatcher里面的一個(gè)內(nèi)部類InnerReceiver,這里調(diào)用它的performReceive函數(shù)。
Step 13. InnerReceiver.performReceive
這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/LoadedApk.java文件中:
final class LoadedApk {
......
static final class ReceiverDispatcher {
final static class InnerReceiver extends IIntentReceiver.Stub {
......
public void performReceive(Intent intent, int resultCode,
String data, Bundle extras, boolean ordered, boolean sticky) {
LoadedApk.ReceiverDispatcher rd = mDispatcher.get();
......
if (rd != null) {
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky);
} else {
......
}
}
}
......
}
......
}
這里,它只是簡(jiǎn)單地調(diào)用ReceiverDispatcher的performReceive函數(shù)來(lái)進(jìn)一步處理,這里的ReceiverDispatcher類是LoadedApk類里面的一個(gè)內(nèi)部類。
Step 14. ReceiverDispatcher.performReceive
這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/LoadedApk.java文件中:
final class LoadedApk {
......
static final class ReceiverDispatcher {
......
public void performReceive(Intent intent, int resultCode,
String data, Bundle extras, boolean ordered, boolean sticky) {
......
Args args = new Args();
args.mCurIntent = intent;
args.mCurCode = resultCode;
args.mCurData = data;
args.mCurMap = extras;
args.mCurOrdered = ordered;
args.mCurSticky = sticky;
if (!mActivityThread.post(args)) {
......
}
}
......
}
......
}
這里mActivityThread成員變量的類型為Handler,它是前面MainActivity注冊(cè)廣播接收器時(shí),從ActivityThread取得的,具體可以參考前面一篇文章
Android應(yīng)用程序注冊(cè)廣播接收器(registerReceiver)的過(guò)程分析中的Step 3。這里ReceiverDispatcher借助這個(gè)Handler,把這個(gè)廣播以消息的形式放到MainActivity所在的這個(gè)ActivityThread的消息隊(duì)列中去,因此,ReceiverDispatcher不等這個(gè)廣播被MainActivity處理就返回了,這里也體現(xiàn)了廣播的發(fā)送和處理是異步進(jìn)行的。
注意這里處理消息的方式是通過(guò)Handler.post函數(shù)進(jìn)行的,post函數(shù)的參數(shù)是Runnable類型的,這個(gè)消息最終會(huì)調(diào)用這個(gè)這個(gè)參數(shù)的run成員函數(shù)來(lái)處理。這里的Args類是LoadedApk類的內(nèi)部類ReceiverDispatcher的一個(gè)內(nèi)部類,它繼承于Runnable類,因此,可以作為mActivityThread.post的參數(shù)傳進(jìn)去,代表這個(gè)廣播的intent也保存在這個(gè)Args實(shí)例中。
Step 15. Hanlder.post
這個(gè)函數(shù)定義在frameworks/base/core/java/android/os/Handler.java文件中,這個(gè)函數(shù)我們就不看了,有興趣的讀者可以自己研究一下,它的作用就是把消息放在消息隊(duì)列中,然后就返回了,這個(gè)消息最終會(huì)在傳進(jìn)來(lái)的Runnable類型的參數(shù)的run成員函數(shù)中進(jìn)行處理。
Step 16. Args.run
這個(gè)函數(shù)定義在frameworks/base/core/java/android/app/LoadedApk.java文件中:
final class LoadedApk {
......
static final class ReceiverDispatcher {
......
final class Args implements Runnable {
......
public void run() {
BroadcastReceiver receiver = mReceiver;
......
Intent intent = mCurIntent;
......
try {
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
if (mCurMap != null) {
mCurMap.setClassLoader(cl);
}
receiver.setOrderedHint(true);
receiver.setResult(mCurCode, mCurData, mCurMap);
receiver.clearAbortBroadcast();
receiver.setOrderedHint(mCurOrdered);
receiver.setInitialStickyHint(mCurSticky);
receiver.onReceive(mContext, intent);
} catch (Exception e) {
......
}
......
}
......
}
......
}
......
}
這里的mReceiver是ReceiverDispatcher類的成員變量,它的類型是BroadcastReceiver,這里它就是MainActivity注冊(cè)廣播接收器時(shí)創(chuàng)建的BroadcastReceiver實(shí)例了,具體可以參考前面一篇文章
Android應(yīng)用程序注冊(cè)廣播接收器(registerReceiver)的過(guò)程分析中的Step 2。
有了這個(gè)ReceiverDispatcher實(shí)例之后,就可以調(diào)用它的onReceive函數(shù)把這個(gè)廣播分發(fā)給它處理了。
Step 17. BroadcastReceiver.onReceive
這個(gè)函數(shù)定義Android系統(tǒng)中的廣播(Broadcast)機(jī)制簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃一文中所介紹的Android應(yīng)用程序Broadcast的工程目錄下的src/shy/luo/broadcast/MainActivity.java文件中:
public class MainActivity extends Activity implements OnClickListener {
......
private BroadcastReceiver counterActionReceiver = new BroadcastReceiver(){
public void onReceive(Context context, Intent intent) {
int counter = intent.getIntExtra(CounterService.COUNTER_VALUE, 0);
String text = String.valueOf(counter);
counterText.setText(text);
Log.i(LOG_TAG, "Receive counter event");
}
}
......
}
這樣,MainActivity里面的定義的BroadcastReceiver實(shí)例counterActionReceiver就收到這個(gè)廣播并進(jìn)行處理了。
至此,Android應(yīng)用程序發(fā)送廣播的過(guò)程就分析完成了,結(jié)合前面這篇分析廣播接收器注冊(cè)過(guò)程的文章
Android應(yīng)用程序注冊(cè)廣播接收器(registerReceiver)的過(guò)程分析,就會(huì)對(duì)Android系統(tǒng)的廣播機(jī)制且個(gè)更深刻的認(rèn)識(shí)和理解了。
最后,我們總結(jié)一下這個(gè)Android應(yīng)用程序發(fā)送廣播的過(guò)程:
1. Step 1 - Step 7,計(jì)數(shù)器服務(wù)CounterService通過(guò)sendBroadcast把一個(gè)廣播通過(guò)Binder進(jìn)程間通信機(jī)制發(fā)送給ActivityManagerService,ActivityManagerService根據(jù)這個(gè)廣播的Action類型找到相應(yīng)的廣播接收器,然后把這個(gè)廣播放進(jìn)自己的消息隊(duì)列中去,就完成第一階段對(duì)這個(gè)廣播的異步分發(fā)了;
2. Step 8 - Step 15,ActivityManagerService在消息循環(huán)中處理這個(gè)廣播,并通過(guò)Binder進(jìn)程間通信機(jī)制把這個(gè)廣播分發(fā)給注冊(cè)的廣播接收分發(fā)器ReceiverDispatcher,ReceiverDispatcher把這個(gè)廣播放進(jìn)MainActivity所在的線程的消息隊(duì)列中去,就完成第二階段對(duì)這個(gè)廣播的異步分發(fā)了;
3. Step 16 - Step 17, ReceiverDispatcher的內(nèi)部類Args在MainActivity所在的線程消息循環(huán)中處理這個(gè)廣播,最終是將這個(gè)廣播分發(fā)給所注冊(cè)的BroadcastReceiver實(shí)例的onReceive函數(shù)進(jìn)行處理。
這樣,Android系統(tǒng)廣播機(jī)制就學(xué)習(xí)完成了,希望對(duì)讀者有所幫助。重新學(xué)習(xí)Android系統(tǒng)的廣播機(jī)制,請(qǐng)回到Android系統(tǒng)中的廣播(Broadcast)機(jī)制簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃一文中。
作者:Luoshengyang 發(fā)表于2011-9-5 1:01:18
原文鏈接
posted on 2012-04-17 21:32
mixer-a 閱讀(7301)
評(píng)論(0) 編輯 收藏