来自:http://blog.csdn.net/luoshengyang/article/details/6744448

前面我们分析了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发送广播的代码如下所示:

[java] view plain copy
  1. publicclassCounterServiceextendsServiceimplementsICounterService{
  2. ......
  3. publicvoidstartCounter(intinitVal){
  4. AsyncTask<Integer,Integer,Integer>task=newAsyncTask<Integer,Integer,Integer>(){
  5. @Override
  6. protectedIntegerdoInBackground(Integer...vals){
  7. ......
  8. }
  9. @Override
  10. protectedvoidonProgressUpdate(Integer...values){
  11. super.onProgressUpdate(values);
  12. intcounter=values[0];
  13. Intentintent=newIntent(BROADCAST_COUNTER_ACTION);
  14. intent.putExtra(COUNTER_VALUE,counter);
  15. sendBroadcast(intent);
  16. }
  17. @Override
  18. protectedvoidonPostExecute(Integerval){
  19. ......
  20. }
  21. };
  22. task.execute(0);
  23. }
  24. ......
  25. }
在onProgressUpdate函数中,创建了一个BROADCAST_COUNTER_ACTION类型的Intent,并且在这里个Intent中附加上当前的计数器值,然后通过CounterService类的成员函数sendBroadcast将这个Intent发送出去。CounterService类继承了Service类,Service类又继承了ContextWrapper类,成员函数sendBroadcast就是从ContextWrapper类继承下来的,因此,我们就从ContextWrapper类的sendBroadcast函数开始,分析广播发送的过程。

在继承分析广播的发送过程前,我们先来看一下广播发送过程的序列图,然后按照这个序图中的步骤来一步一步分析整个过程。


点击查看大图

Step 1. ContextWrapper.sendBroadcast

这个函数定义在frameworks/base/core/java/android/content/ContextWrapper.java文件中:

[java] view plain copy
  1. publicclassContextWrapperextendsContext{
  2. ContextmBase;
  3. ......
  4. @Override
  5. publicvoidsendBroadcast(Intentintent){
  6. mBase.sendBroadcast(intent);
  7. }
  8. ......
  9. }
这里的成员变量mBase是一个ContextImpl实例,这里只简单地调用ContextImpl.sendBroadcast进一行操作。

Step 2.ContextImpl.sendBroadcast

这个函数定义在frameworks/base/core/java/android/app/ContextImpl.java文件中:

[java] view plain copy
  1. classContextImplextendsContext{
  2. ......
  3. @Override
  4. publicvoidsendBroadcast(Intentintent){
  5. StringresolvedType=intent.resolveTypeIfNeeded(getContentResolver());
  6. try{
  7. ActivityManagerNative.getDefault().broadcastIntent(
  8. mMainThread.getApplicationThread(),intent,resolvedType,null,
  9. Activity.RESULT_OK,null,null,null,false,false);
  10. }catch(RemoteExceptione){
  11. }
  12. }
  13. ......
  14. }
这里的resolvedType表示这个Intent的MIME类型,我们没有设置这个Intent的MIME类型,因此,这里的resolvedType为null。接下来就调用ActivityManagerService的远程接口ActivityManagerProxy把这个广播发送给ActivityManagerService了。

Step 3.ActivityManagerProxy.broadcastIntent

这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

[java] view plain copy
  1. classActivityManagerProxyimplementsIActivityManager
  2. {
  3. ......
  4. publicintbroadcastIntent(IApplicationThreadcaller,
  5. Intentintent,StringresolvedType,IIntentReceiverresultTo,
  6. intresultCode,StringresultData,Bundlemap,
  7. StringrequiredPermission,booleanserialized,
  8. booleansticky)throwsRemoteException
  9. {
  10. Parceldata=Parcel.obtain();
  11. Parcelreply=Parcel.obtain();
  12. data.writeInterfaceToken(IActivityManager.descriptor);
  13. data.writeStrongBinder(caller!=null?caller.asBinder():null);
  14. intent.writeToParcel(data,0);
  15. data.writeString(resolvedType);
  16. data.writeStrongBinder(resultTo!=null?resultTo.asBinder():null);
  17. data.writeInt(resultCode);
  18. data.writeString(resultData);
  19. data.writeBundle(map);
  20. data.writeString(requiredPermission);
  21. data.writeInt(serialized?1:0);
  22. data.writeInt(sticky?1:0);
  23. mRemote.transact(BROADCAST_INTENT_TRANSACTION,data,reply,0);
  24. reply.readException();
  25. intres=reply.readInt();
  26. reply.recycle();
  27. data.recycle();
  28. returnres;
  29. }
  30. ......
  31. }
这里的实现比较简单,把要传递的参数封装好,然后通过Binder驱动程序进入到ActivityManagerService的broadcastIntent函数中。

Step 4.ctivityManagerService.broadcastIntent

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

[java] view plain copy
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. publicfinalintbroadcastIntent(IApplicationThreadcaller,
  5. Intentintent,StringresolvedType,IIntentReceiverresultTo,
  6. intresultCode,StringresultData,Bundlemap,
  7. StringrequiredPermission,booleanserialized,booleansticky){
  8. synchronized(this){
  9. intent=verifyBroadcastLocked(intent);
  10. finalProcessRecordcallerApp=getRecordForAppLocked(caller);
  11. finalintcallingPid=Binder.getCallingPid();
  12. finalintcallingUid=Binder.getCallingUid();
  13. finallongorigId=Binder.clearCallingIdentity();
  14. intres=broadcastIntentLocked(callerApp,
  15. callerApp!=null?callerApp.info.packageName:null,
  16. intent,resolvedType,resultTo,
  17. resultCode,resultData,map,requiredPermission,serialized,
  18. sticky,callingPid,callingUid);
  19. Binder.restoreCallingIdentity(origId);
  20. returnres;
  21. }
  22. }
  23. ......
  24. }
这里调用broadcastIntentLocked函数来进一步处理。

Step 5.ActivityManagerService.broadcastIntentLocked

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

[java] view plain copy
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. privatefinalintbroadcastIntentLocked(ProcessRecordcallerApp,
  5. StringcallerPackage,Intentintent,StringresolvedType,
  6. IIntentReceiverresultTo,intresultCode,StringresultData,
  7. Bundlemap,StringrequiredPermission,
  8. booleanordered,booleansticky,intcallingPid,intcallingUid){
  9. intent=newIntent(intent);
  10. ......
  11. //Figureoutwhoallwillreceivethisbroadcast.
  12. Listreceivers=null;
  13. List<BroadcastFilter>registeredReceivers=null;
  14. try{
  15. if(intent.getComponent()!=null){
  16. ......
  17. }else{
  18. ......
  19. registeredReceivers=mReceiverResolver.queryIntent(intent,resolvedType,false);
  20. }
  21. }catch(RemoteExceptionex){
  22. ......
  23. }
  24. finalbooleanreplacePending=
  25. (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING)!=0;
  26. intNR=registeredReceivers!=null?registeredReceivers.size():0;
  27. if(!ordered&&NR>0){
  28. //Ifwearenotserializingthisbroadcast,thensendthe
  29. //registeredreceiversseparatelysotheydon'twaitforthe
  30. //componentstobelaunched.
  31. BroadcastRecordr=newBroadcastRecord(intent,callerApp,
  32. callerPackage,callingPid,callingUid,requiredPermission,
  33. registeredReceivers,resultTo,resultCode,resultData,map,
  34. ordered,sticky,false);
  35. ......
  36. booleanreplaced=false;
  37. if(replacePending){
  38. for(inti=mParallelBroadcasts.size()-1;i>=0;i--){
  39. if(intent.filterEquals(mParallelBroadcasts.get(i).intent)){
  40. ......
  41. mParallelBroadcasts.set(i,r);
  42. replaced=true;
  43. break;
  44. }
  45. }
  46. }
  47. if(!replaced){
  48. mParallelBroadcasts.add(r);
  49. scheduleBroadcastsLocked();
  50. }
  51. registeredReceivers=null;
  52. NR=0;
  53. }
  54. ......
  55. }
  56. ......
  57. }
这个函数首先是根据intent找出相应的广播接收器: [java] view plain copy
  1. //Figureoutwhoallwillreceivethisbroadcast.
  2. Listreceivers=null;
  3. List<BroadcastFilter>registeredReceivers=null;
  4. try{
  5. if(intent.getComponent()!=null){
  6. ......
  7. }else{
  8. ......
  9. registeredReceivers=mReceiverResolver.queryIntent(intent,resolvedType,false);
  10. }
  11. }catch(RemoteExceptionex){
  12. ......
  13. }
回忆一下前面一篇文章 Android应用程序注册广播接收器(registerReceiver)的过程分析中的Step 6(ActivityManagerService.registerReceiver)中,我们将一个filter类型为BROADCAST_COUNTER_ACTION类型的BroadcastFilter实例保存在了ActivityManagerService的成员变量mReceiverResolver中,这个BroadcastFilter实例包含了我们所注册的广播接收器,这里就通过mReceiverResolver.queryIntent函数将这个BroadcastFilter实例取回来。由于注册一个广播类型的接收器可能有多个,所以这里把所有符合条件的的BroadcastFilter实例放在一个List中,然后返回来。在我们这个场景中,这个List就只有一个BroadcastFilter实例了,就是MainActivity注册的那个广播接收器。

继续往下看:

[java] view plain copy
  1. finalbooleanreplacePending=
  2. (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING)!=0;
这里是查看一下这个intent的Intent.FLAG_RECEIVER_REPLACE_PENDING位有没有设置,如果设置了的话,ActivityManagerService就会在当前的系统中查看有没有相同的intent还未被处理,如果有的话,就有当前这个新的intent来替换旧的intent。这里,我们没有设置intent的Intent.FLAG_RECEIVER_REPLACE_PENDING位,因此,这里的replacePending变量为false。

再接着往下看:

[java] view plain copy
  1. intNR=registeredReceivers!=null?registeredReceivers.size():0;
  2. if(!ordered&&NR>0){
  3. //Ifwearenotserializingthisbroadcast,thensendthe
  4. //registeredreceiversseparatelysotheydon'twaitforthe
  5. //componentstobelaunched.
  6. BroadcastRecordr=newBroadcastRecord(intent,callerApp,
  7. callerPackage,callingPid,callingUid,requiredPermission,
  8. registeredReceivers,resultTo,resultCode,resultData,map,
  9. ordered,sticky,false);
  10. ......
  11. booleanreplaced=false;
  12. if(replacePending){
  13. for(inti=mParallelBroadcasts.size()-1;i>=0;i--){
  14. if(intent.filterEquals(mParallelBroadcasts.get(i).intent)){
  15. ......
  16. mParallelBroadcasts.set(i,r);
  17. replaced=true;
  18. break;
  19. }
  20. }
  21. }
  22. if(!replaced){
  23. mParallelBroadcasts.add(r);
  24. scheduleBroadcastsLocked();
  25. }
  26. registeredReceivers=null;
  27. NR=0;
  28. }
前面我们说到,这里得到的列表registeredReceivers的大小为1,且传进来的参数ordered为false,表示要将这个广播发送给所有注册了BROADCAST_COUNTER_ACTION类型广播的接收器,因此,会执行下面的if语句。这个if语句首先创建一个广播记录块BroadcastRecord,里面记录了这个广播是由谁发出的以及要发给谁等相关信息。由于前面得到的replacePending变量为false,因此,不会执行接下来的if语句,即不会检查系统中是否有相同类型的未处理的广播。

这样,这里得到的replaced变量的值也为false,于是,就会把这个广播记录块r放在ActivityManagerService的成员变量mParcelBroadcasts中,等待进一步处理;进一步处理的操作由函数scheduleBroadcastsLocked进行。

Step 6.ActivityManagerService.scheduleBroadcastsLocked

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

[java] view plain copy
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. privatefinalvoidscheduleBroadcastsLocked(){
  5. ......
  6. if(mBroadcastsScheduled){
  7. return;
  8. }
  9. mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
  10. mBroadcastsScheduled=true;
  11. }
  12. ......
  13. }
这里的mBroadcastsScheduled表示ActivityManagerService当前是不是正在处理其它广播,如果是的话,这里就先不处理直接返回了,保证所有广播串行处理。

注意这里处理广播的方式,它是通过消息循环来处理,每当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函数来真正处理这个消息:

[java] view plain copy
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. finalHandlermHandler=newHandler(){
  5. publicvoidhandleMessage(Messagemsg){
  6. switch(msg.what){
  7. ......
  8. caseBROADCAST_INTENT_MSG:{
  9. ......
  10. processNextBroadcast(true);
  11. }break;
  12. ......
  13. }
  14. }
  15. }
  16. ......
  17. }
这里又调用了ActivityManagerService的processNextBroadcast函数来处理下一个未处理的广播。

Step 8.ActivityManagerService.processNextBroadcast

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

[java] view plain copy
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. privatefinalvoidprocessNextBroadcast(booleanfromMsg){
  5. synchronized(this){
  6. BroadcastRecordr;
  7. ......
  8. if(fromMsg){
  9. mBroadcastsScheduled=false;
  10. }
  11. //First,deliveranynon-serializedbroadcastsrightaway.
  12. while(mParallelBroadcasts.size()>0){
  13. r=mParallelBroadcasts.remove(0);
  14. ......
  15. finalintN=r.receivers.size();
  16. ......
  17. for(inti=0;i<N;i++){
  18. Objecttarget=r.receivers.get(i);
  19. ......
  20. deliverToRegisteredReceiverLocked(r,(BroadcastFilter)target,false);
  21. }
  22. addBroadcastToHistoryLocked(r);
  23. ......
  24. }
  25. ......
  26. }
  27. }
  28. ......
  29. }
这里传进来的参数fromMsg为true,于是把mBroadcastScheduled重新设为false,这样,下一个广播就能进入到消息队列中进行处理了。前面我们在Step 5中,把一个广播记录块BroadcastRecord放在了mParallelBroadcasts中,因此,这里就把它取出来进行处理了。广播记录块BroadcastRecord的receivers列表中包含了要接收这个广播的目标列表,即前面我们注册的广播接收器,用BroadcastFilter来表示,这里while循环中的for循环就是把这个广播发送给每一个订阅了该广播的接收器了,通过deliverToRegisteredReceiverLocked函数执行。

Step 9.ActivityManagerService.deliverToRegisteredReceiverLocked

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

[java] view plain copy
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. privatefinalvoiddeliverToRegisteredReceiverLocked(BroadcastRecordr,
  5. BroadcastFilterfilter,booleanordered){
  6. booleanskip=false;
  7. if(filter.requiredPermission!=null){
  8. ......
  9. }
  10. if(r.requiredPermission!=null){
  11. ......
  12. }
  13. if(!skip){
  14. //Ifthisisnotbeingsentasanorderedbroadcast,thenwe
  15. //don'twanttotouchthefieldsthatkeeptrackofthecurrent
  16. //stateoforderedbroadcasts.
  17. if(ordered){
  18. ......
  19. }
  20. try{
  21. ......
  22. performReceiveLocked(filter.receiverList.app,filter.receiverList.receiver,
  23. newIntent(r.intent),r.resultCode,
  24. r.resultData,r.resultExtras,r.ordered,r.initialSticky);
  25. ......
  26. }catch(RemoteExceptione){
  27. ......
  28. }
  29. }
  30. }
  31. ......
  32. }
函数首先是检查一下广播发送和接收的权限,在我们分析的这个场景中,没有设置权限,因此,这个权限检查就跳过了,这里得到的skip为false,于是进入下面的if语句中。由于上面传时来的ordered参数为false,因此,直接就调用performReceiveLocked函数来进一步执行广播发送的操作了。

Step 10.ActivityManagerService.performReceiveLocked

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

[java] view plain copy
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. staticvoidperformReceiveLocked(ProcessRecordapp,IIntentReceiverreceiver,
  5. Intentintent,intresultCode,Stringdata,Bundleextras,
  6. booleanordered,booleansticky)throwsRemoteException{
  7. //Sendtheintenttothereceiverasynchronouslyusingone-waybindercalls.
  8. if(app!=null&&app.thread!=null){
  9. //Ifwehaveanappthread,dothecallthroughthatsoitis
  10. //correctlyorderedwithotherone-waycalls.
  11. app.thread.scheduleRegisteredReceiver(receiver,intent,resultCode,
  12. data,extras,ordered,sticky);
  13. }else{
  14. ......
  15. }
  16. }
  17. ......
  18. }
注意,这里传进来的参数app是注册广播接收器的Activity所在的进程记录块,在我们分析的这个场景中,由于是MainActivity调用registerReceiver函数来注册这个广播接收器的,因此,参数app所代表的ProcessRecord就是MainActivity所在的进程记录块了;而参数receiver也是注册广播接收器时传给ActivityManagerService的一个Binder对象,它的类型是IIntentReceiver,具体可以参考上一篇文章 Android应用程序注册广播接收器(registerReceiver)的过程分析中的Step 2。

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文件中:

[java] view plain copy
  1. classApplicationThreadProxyimplementsIApplicationThread{
  2. ......
  3. publicvoidscheduleRegisteredReceiver(IIntentReceiverreceiver,Intentintent,
  4. intresultCode,StringdataStr,Bundleextras,booleanordered,booleansticky)
  5. throwsRemoteException{
  6. Parceldata=Parcel.obtain();
  7. data.writeInterfaceToken(IApplicationThread.descriptor);
  8. data.writeStrongBinder(receiver.asBinder());
  9. intent.writeToParcel(data,0);
  10. data.writeInt(resultCode);
  11. data.writeString(dataStr);
  12. data.writeBundle(extras);
  13. data.writeInt(ordered?1:0);
  14. data.writeInt(sticky?1:0);
  15. mRemote.transact(SCHEDULE_REGISTERED_RECEIVER_TRANSACTION,data,null,
  16. IBinder.FLAG_ONEWAY);
  17. data.recycle();
  18. }
  19. ......
  20. }
这里通过Binder驱动程序就进入到ApplicationThread.scheduleRegisteredReceiver函数去了。ApplicationThread是ActivityThread的一个内部类,具体可以参考Activity启动主题 Android应用程序的Activity启动过程简要介绍和学习计划。

Step 12.ApplicaitonThread.scheduleRegisteredReceiver
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

[java] view plain copy
  1. publicfinalclassActivityThread{
  2. ......
  3. privatefinalclassApplicationThreadextendsApplicationThreadNative{
  4. ......
  5. //Thisfunctionexiststomakesureallreceiverdispatchingis
  6. //correctlyordered,sincetheseareone-waycallsandthebinderdriver
  7. //appliestransactionorderingperobjectforsuchcalls.
  8. publicvoidscheduleRegisteredReceiver(IIntentReceiverreceiver,Intentintent,
  9. intresultCode,StringdataStr,Bundleextras,booleanordered,
  10. booleansticky)throwsRemoteException{
  11. receiver.performReceive(intent,resultCode,dataStr,extras,ordered,sticky);
  12. }
  13. ......
  14. }
  15. ......
  16. }
这里的receiver是在前面一篇文章 Android应用程序注册广播接收器(registerReceiver)的过程分析中的Step 4中创建的,它的具体类型是LoadedApk.ReceiverDispatcher.InnerReceiver,即定义在LoadedApk类的内部类ReceiverDispatcher里面的一个内部类InnerReceiver,这里调用它的performReceive函数。

Step 13.InnerReceiver.performReceive

这个函数定义在frameworks/base/core/java/android/app/LoadedApk.java文件中:

[java] view plain copy
  1. finalclassLoadedApk{
  2. ......
  3. staticfinalclassReceiverDispatcher{
  4. finalstaticclassInnerReceiverextendsIIntentReceiver.Stub{
  5. ......
  6. publicvoidperformReceive(Intentintent,intresultCode,
  7. Stringdata,Bundleextras,booleanordered,booleansticky){
  8. LoadedApk.ReceiverDispatcherrd=mDispatcher.get();
  9. ......
  10. if(rd!=null){
  11. rd.performReceive(intent,resultCode,data,extras,
  12. ordered,sticky);
  13. }else{
  14. ......
  15. }
  16. }
  17. }
  18. ......
  19. }
  20. ......
  21. }
这里,它只是简单地调用ReceiverDispatcher的performReceive函数来进一步处理,这里的ReceiverDispatcher类是LoadedApk类里面的一个内部类。

Step 14.ReceiverDispatcher.performReceive

这个函数定义在frameworks/base/core/java/android/app/LoadedApk.java文件中:

[java] view plain copy
  1. finalclassLoadedApk{
  2. ......
  3. staticfinalclassReceiverDispatcher{
  4. ......
  5. publicvoidperformReceive(Intentintent,intresultCode,
  6. Stringdata,Bundleextras,booleanordered,booleansticky){
  7. ......
  8. Argsargs=newArgs();
  9. args.mCurIntent=intent;
  10. args.mCurCode=resultCode;
  11. args.mCurData=data;
  12. args.mCurMap=extras;
  13. args.mCurOrdered=ordered;
  14. args.mCurSticky=sticky;
  15. if(!mActivityThread.post(args)){
  16. ......
  17. }
  18. }
  19. ......
  20. }
  21. ......
  22. }
这里mActivityThread成员变量的类型为Handler,它是前面MainActivity注册广播接收器时,从ActivityThread取得的,具体可以参考前面一篇文章 Android应用程序注册广播接收器(registerReceiver)的过程分析中的Step 3。这里ReceiverDispatcher借助这个Handler,把这个广播以消息的形式放到MainActivity所在的这个ActivityThread的消息队列中去,因此,ReceiverDispatcher不等这个广播被MainActivity处理就返回了,这里也体现了广播的发送和处理是异步进行的。

注意这里处理消息的方式是通过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文件中:

[java] view plain copy
  1. finalclassLoadedApk{
  2. ......
  3. staticfinalclassReceiverDispatcher{
  4. ......
  5. finalclassArgsimplementsRunnable{
  6. ......
  7. publicvoidrun(){
  8. BroadcastReceiverreceiver=mReceiver;
  9. ......
  10. Intentintent=mCurIntent;
  11. ......
  12. try{
  13. ClassLoadercl=mReceiver.getClass().getClassLoader();
  14. intent.setExtrasClassLoader(cl);
  15. if(mCurMap!=null){
  16. mCurMap.setClassLoader(cl);
  17. }
  18. receiver.setOrderedHint(true);
  19. receiver.setResult(mCurCode,mCurData,mCurMap);
  20. receiver.clearAbortBroadcast();
  21. receiver.setOrderedHint(mCurOrdered);
  22. receiver.setInitialStickyHint(mCurSticky);
  23. receiver.onReceive(mContext,intent);
  24. }catch(Exceptione){
  25. ......
  26. }
  27. ......
  28. }
  29. ......
  30. }
  31. ......
  32. }
  33. ......
  34. }
这里的mReceiver是ReceiverDispatcher类的成员变量,它的类型是BroadcastReceiver,这里它就是MainActivity注册广播接收器时创建的BroadcastReceiver实例了,具体可以参考前面一篇文章 Android应用程序注册广播接收器(registerReceiver)的过程分析中的Step 2。

有了这个ReceiverDispatcher实例之后,就可以调用它的onReceive函数把这个广播分发给它处理了。

Step 17. BroadcastReceiver.onReceive

这个函数定义Android系统中的广播(Broadcast)机制简要介绍和学习计划一文中所介绍的Android应用程序Broadcast的工程目录下的src/shy/luo/broadcast/MainActivity.java文件中:

[java] view plain copy
  1. publicclassMainActivityextendsActivityimplementsOnClickListener{
  2. ......
  3. privateBroadcastReceivercounterActionReceiver=newBroadcastReceiver(){
  4. publicvoidonReceive(Contextcontext,Intentintent){
  5. intcounter=intent.getIntExtra(CounterService.COUNTER_VALUE,0);
  6. Stringtext=String.valueOf(counter);
  7. counterText.setText(text);
  8. Log.i(LOG_TAG,"Receivecounterevent");
  9. }
  10. }
  11. ......
  12. }
这样,MainActivity里面的定义的BroadcastReceiver实例counterActionReceiver就收到这个广播并进行处理了。
至此,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)机制简要介绍和学习计划一文中。


更多相关文章

  1. C语言函数的递归(上)
  2. Android(安卓)Window类解析
  3. 新版NDK环境搭建(免Cygwin,超级快)
  4. Android(安卓)自定义View - 启航 一般View定义
  5. android.widget.Toast——快显信息
  6. Android(安卓)ImageSpan与TextView中的text居中对齐问题解决(无论
  7. lambda表达式介绍以及Android(安卓)Studio引入lambda
  8. [置顶] Android(安卓)Launcher全面剖析
  9. getevent工具和Android中inputevent的分析

随机推荐

  1. node-webkit解析excel文档
  2. vue学习系列-认识vue.js
  3. 在AppCode中的razor调用HtmlHelper方法和
  4. html5炸金花棋牌开发
  5. HTML5中Canvas与SVG的画图原理比较
  6. 详解 转发 https://www.cnblogs.com/figh
  7. 如何使用“left:100%”CSS规则保留DIV宽度
  8. 嵌入的图像在签名中不显示。
  9. 急!!!在eclipse中,如何对某个html不做验证
  10. 百度一下就知道