前面我们分析了Android应用程序注册广播接收器的过程,这个过程只完成了万里长征的第一步,接下来它还要等待ActivityManagerService将广播分发过来。ActivityManagerService是如何得到广播并把它分发出去的呢?这就是本文要介绍的广播发送过程了。
广播的发送过程比广播接收器的注册过程要复杂得多了,不过这个过程仍然是以ActivityManagerService为中心。广播的发送者将广播发送到ActivityManagerService,ActivityManagerService接收到这个广播以后,就会在自己的注册中心查看有哪些广播接收器订阅了该广播,然后把这个广播逐一发送到这些广播接收器中,但是ActivityManagerService并不等待广播接收器处理这些广播就返回了,因此,广播的发送和处理是异步的。概括来说,广播的发送路径就是从发送者到ActivityManagerService,再从ActivityManagerService到接收者,这中间的两个过程都是通过Binder进程间通信机制来完成的,因此,希望读者在继续阅读本文之前,对Android系统的Binder进程间通信机制有所了解,具体可以参考Android进程间通信(IPC)机制Binder简要介绍和学习计划一文。
本文继续以Android系统中的广播(Broadcast)机制简要介绍和学习计划一文中所开发的应用程序为例子,并且结合上文Android应用程序注册广播接收器(registerReceiver)的过程分析的内容,一起来分析Android应用程序发送广播的过程。
回顾一下Android系统中的广播(Broadcast)机制简要介绍和学习计划一文中所开发的应用程序的组织架构,MainActivity向ActivityManagerService注册了一个CounterService.BROADCAST_COUNTER_ACTION类型的计数器服务广播接收器,计数器服务CounterService在后台线程中启动了一个异步任务(AsyncTask),这个异步任务负责不断地增加计数,并且不断地将当前计数值通过广播的形式发送出去,以便MainActivity可以将当前计数值在应用程序的界面线程中显示出来。
计数器服务CounterService发送广播的代码如下所示:
- 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);
- }
- ......
- }
在继承分析广播的发送过程前,我们先来看一下广播发送过程的序列图,然后按照这个序图中的步骤来一步一步分析整个过程。
Step 1. ContextWrapper.sendBroadcast
这个函数定义在frameworks/base/core/java/android/content/ContextWrapper.java文件中:
- public class ContextWrapper extends Context {
- Context mBase;
- ......
- @Override
- public void sendBroadcast(Intent intent) {
- mBase.sendBroadcast(intent);
- }
- ......
- }
Step 2. ContextImpl.sendBroadcast
这个函数定义在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) {
- }
- }
- ......
- }
Step 3. ActivityManagerProxy.broadcastIntent
这个函数定义在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;
- }
- ......
- }
Step 4. ctivityManagerService.broadcastIntent
这个函数定义在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;
- }
- }
- ......
- }
Step 5. ActivityManagerService.broadcastIntentLocked
这个函数定义在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;
- }
- ......
- }
- ......
- }
- // 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;
- }
这样,这里得到的replaced变量的值也为false,于是,就会把这个广播记录块r放在ActivityManagerService的成员变量mParcelBroadcasts中,等待进一步处理;进一步处理的操作由函数scheduleBroadcastsLocked进行。
Step 6. ActivityManagerService.scheduleBroadcastsLocked
这个函数定义在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;
- }
- ......
- }
注意这里处理广播的方式,它是通过消息循环来处理,每当ActivityManagerService接收到一个广播时,它就把这个广播放进自己的消息队列去就完事了,根本不管这个广播后续是处理的,因此,这里我们可以看出广播的发送和处理是异步的。
这里的成员变量mHandler是一个在ActivityManagerService内部定义的Handler类变量,通过它的sendEmptyMessage函数把一个类型为BROADCAST_INTENT_MSG的空消息放进ActivityManagerService的消息队列中去。这里的空消息是指这个消息除了有类型信息之外,没有任何其它额外的信息,因为前面已经把要处理的广播信息都保存在mParcelBroadcasts中了,等处理这个消息时,从mParcelBroadcasts就可以读回相关的广播信息了,因此,这里不需要把广播信息再放在消息内容中。
Step 7. Handler.sendEmptyMessage
这个自定义的Handler类实现在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中,它是ActivityManagerService的内部类,调用了它的sendEmptyMessage函数来把一个消息放到消息队列后,一会就会调用它的handleMessage函数来真正处理这个消息:
- 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;
- ......
- }
- }
- }
- ......
- }
Step 8. ActivityManagerService.processNextBroadcast
这个函数定义在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);
- ......
- }
- ......
- }
- }
- ......
- }
Step 9. ActivityManagerService.deliverToRegisteredReceiverLocked
这个函数定义在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) {
- ......
- }
- }
- }
- ......
- }
Step 10. ActivityManagerService.performReceiveLocked
这个函数定义在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 {
- ......
- }
- }
- ......
- }
MainActivity在注册广播接收器时,已经把自己的ProcessRecord记录下来了,所以这里的参数app和app.thread均不为null,于是,ActivityManagerService就调用app.thread.scheduleRegisteredReceiver函数来把这个广播分发给MainActivity了。这里的app.thread是一个Binder远程对象,它的类型是ApplicationThreadProxy,我们在前面介绍应用程序的Activity启动过程时,已经多次看到了,具体可以参考主题Android应用程序的Activity启动过程简要介绍和学习计划。
Step 11. ApplicationThreadProxy.scheduleRegisteredReceiver
这个函数定义在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();
- }
- ......
- }
Step 12. ApplicaitonThread.scheduleRegisteredReceiver
这个函数定义在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);
- }
- ......
- }
- ......
- }
Step 13. InnerReceiver.performReceive
这个函数定义在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 {
- ......
- }
- }
- }
- ......
- }
- ......
- }
Step 14. ReceiverDispatcher.performReceive
这个函数定义在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)) {
- ......
- }
- }
- ......
- }
- ......
- }
注意这里处理消息的方式是通过Handler.post函数进行的,post函数的参数是Runnable类型的,这个消息最终会调用这个这个参数的run成员函数来处理。这里的Args类是LoadedApk类的内部类ReceiverDispatcher的一个内部类,它继承于Runnable类,因此,可以作为mActivityThread.post的参数传进去,代表这个广播的intent也保存在这个Args实例中。
Step 15. Hanlder.post
这个函数定义在frameworks/base/core/java/android/os/Handler.java文件中,这个函数我们就不看了,有兴趣的读者可以自己研究一下,它的作用就是把消息放在消息队列中,然后就返回了,这个消息最终会在传进来的Runnable类型的参数的run成员函数中进行处理。
Step 16. Args.run
这个函数定义在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) {
- ......
- }
- ......
- }
- ......
- }
- ......
- }
- ......
- }
有了这个ReceiverDispatcher实例之后,就可以调用它的onReceive函数把这个广播分发给它处理了。
Step 17. BroadcastReceiver.onReceive
这个函数定义Android系统中的广播(Broadcast)机制简要介绍和学习计划一文中所介绍的Android应用程序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");
- }
- }
- ......
- }
至此,Android应用程序发送广播的过程就分析完成了,结合前面这篇分析广播接收器注册过程的文章 Android应用程序注册广播接收器(registerReceiver)的过程分析,就会对Android系统的广播机制且个更深刻的认识和理解了。
最后,我们总结一下这个Android应用程序发送广播的过程:
1. Step 1 - Step 7,计数器服务CounterService通过sendBroadcast把一个广播通过Binder进程间通信机制发送给ActivityManagerService,ActivityManagerService根据这个广播的Action类型找到相应的广播接收器,然后把这个广播放进自己的消息队列中去,就完成第一阶段对这个广播的异步分发了;
2. Step 8 - Step 15,ActivityManagerService在消息循环中处理这个广播,并通过Binder进程间通信机制把这个广播分发给注册的广播接收分发器ReceiverDispatcher,ReceiverDispatcher把这个广播放进MainActivity所在的线程的消息队列中去,就完成第二阶段对这个广播的异步分发了;
3. Step 16 - Step 17, ReceiverDispatcher的内部类Args在MainActivity所在的线程消息循环中处理这个广播,最终是将这个广播分发给所注册的BroadcastReceiver实例的onReceive函数进行处理。
这样,Android系统广播机制就学习完成了,希望对读者有所帮助。重新学习Android系统的广播机制,请回到Android系统中的广播(Broadcast)机制简要介绍和学习计划一文中。
老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注!
-
顶
- 21
-
踩
- 2
-
18楼
abuseyou 2013-01-09 15:45发表 [回复]
-
-
关于Step6,Step7有个问题请教一下。假如连续发送2个广播,考虑这样一个Timing,Intent 1在Step6的处理中发完Message使得mBroadcastsScheduled被设置为true,但Step7中的消息队列中该消息还没有被处理。这个时候Intent 2在Step6中的处理中看到mBroadcastsScheduled = true,于是直接返回。我想问的是,当消息队列中Intent 1的那条消息被处理完成使得mBroadcastsScheduled又被设置为false之后,Intent 2是在哪里又能进入Step6的函数重新进行处理,发Message进消息队列呢?
-
Re:
罗升阳 2013-01-09 15:56发表 [回复]
-
- 回复abuseyou:mBroadcastsScheduled表示的是一次调度,它的调度队列中有若干过Intent在等待发送,这些Intent都会在当前调度中被处理,因此,你说的Intent2会得到处理。
-
-
17楼
androidchuxueze 2012-12-22 11:45发表 [回复]
-
- 不错,花两天时间总算把广播机制弄明白了
-
16楼
tianxuexuankui 2012-12-13 15:31发表 [回复]
-
-
嗯,是在PC段执行的程序,我想在java中潜入cmd命令或者是socket通信之类的是否可以实现发送broadcast给手机,让手机端接收这个命令,进行相关的操作。-
Re:
tianxuexuankui 2012-12-13 15:33发表 [回复]
-
- 回复tianxuexuankui:最近在做一个项目,里面可能会需要相类似的操作。我的联系方式:QQ975398325.希望罗老师能够给予指导,也很欢迎给位朋友加我好友一起研究。
-
-
15楼
tianxuexuankui 2012-12-13 15:16发表 [回复]
-
- 老罗你好,我想问个问题,就是在java程序中能否向手机发送Broadcast,然后在手机端安装一个写好的带有BroadcastReceiver的程序进行接收,然后进行相关的操作呢?
-
14楼
pentiumchen 2012-10-31 14:17发表 [回复]
-
- 罗老师,看了你的分析收获很大,但是还有一点我不是很理解,就是android的广播适用于哪些应用场景,按照我的理解,您据的那个计数器的例子,如果没有跨进程的话用一个最简单的监听者模式就可以实现了,广播涉及到了远程调用有些性能消耗,广播是不是只适用跨进程的情况?
-
12楼
shangyu0801 2012-07-11 14:51发表 [回复]
-
- 厉害,顶一下。
-
11楼
songjam 2012-06-20 17:09发表 [回复]
-
- 写得很详细,看代码在Step 16. Args.run在执行完onReceive之后,好像还要通知AMS,本Receiver处理完成,作为Step 18咋样?
-
10楼
a06063175 2012-06-06 11:35发表 [回复]
-
-
能收到您的回复很激动啊,呵呵,找到了。您说的很对
broadcastIntentLocked方法中的mReceiverResolver.queryIntent方法,就是
frameworks\base\services\java\com\android\server\IntentReslover.java 里的queryIntent(),其中有调用了sortResults(finalList);最后是:
protected void sortResults(List<R> results) {
Collections.sort(results, mResolvePrioritySorter);
}
不知道我找的对不对。之前把frameworks中含有Collections.sort的文件都搜了一遍都没找到,真是思路有大问题,衷心的感谢您!-
Re:
Sailent 2012-06-08 20:32发表 [回复]
-
-
回复a06063175:官方说优先级的设置范围是-1000到1000,但是源码中好像没看到有这个限制,仅仅是2个int型在做比较,实际的优先级范围应该是+-2147483647吧?
另外,那2个列表合并的代码在哪里啊?
-
Re:
罗升阳 2012-06-06 13:27发表 [回复]
-
-
回复a06063175:对于有序广播来说,ActivityManagerService.broadcastIntentLocked是这样处理的:
1. 找到静态注册的广播接收者,存在有一个列表里面,并且已经是按照优先级排好序了的。
2. 找到动态注册的广播接收者,也是存在一个列表里面,也是已经按照优先级排好序了的。
3. 对上面两个列表的广播接收者进行合并,合并的规则是优先级高的排在前面,优先级低的排在后面。如果一个静态注册的广播接收者的优先级和一个动态注册的广播接收者的优先级一样,那么动态注册的广播接收者排在前面。
对所有的广播接收者排好序之后,就可以依次把广播发送它们了。
-