Android应用程序发送广播(sendBroadcast)的过程分析
来自: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- publicclassCounterServiceextendsServiceimplementsICounterService{
- ......
- publicvoidstartCounter(intinitVal){
- AsyncTask<Integer,Integer,Integer>task=newAsyncTask<Integer,Integer,Integer>(){
- @Override
- protectedIntegerdoInBackground(Integer...vals){
- ......
- }
- @Override
- protectedvoidonProgressUpdate(Integer...values){
- super.onProgressUpdate(values);
- intcounter=values[0];
- Intentintent=newIntent(BROADCAST_COUNTER_ACTION);
- intent.putExtra(COUNTER_VALUE,counter);
- sendBroadcast(intent);
- }
- @Override
- protectedvoidonPostExecute(Integerval){
- ......
- }
- };
- task.execute(0);
- }
- ......
- }
在继承分析广播的发送过程前,我们先来看一下广播发送过程的序列图,然后按照这个序图中的步骤来一步一步分析整个过程。
点击查看大图
Step 1. ContextWrapper.sendBroadcast
这个函数定义在frameworks/base/core/java/android/content/ContextWrapper.java文件中:
[java] view plain copy- publicclassContextWrapperextendsContext{
- ContextmBase;
- ......
- @Override
- publicvoidsendBroadcast(Intentintent){
- mBase.sendBroadcast(intent);
- }
- ......
- }
Step 2.ContextImpl.sendBroadcast
这个函数定义在frameworks/base/core/java/android/app/ContextImpl.java文件中:
- classContextImplextendsContext{
- ......
- @Override
- publicvoidsendBroadcast(Intentintent){
- StringresolvedType=intent.resolveTypeIfNeeded(getContentResolver());
- try{
- ActivityManagerNative.getDefault().broadcastIntent(
- mMainThread.getApplicationThread(),intent,resolvedType,null,
- Activity.RESULT_OK,null,null,null,false,false);
- }catch(RemoteExceptione){
- }
- }
- ......
- }
Step 3.ActivityManagerProxy.broadcastIntent
这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:
[java] view plain copy- classActivityManagerProxyimplementsIActivityManager
- {
- ......
- publicintbroadcastIntent(IApplicationThreadcaller,
- Intentintent,StringresolvedType,IIntentReceiverresultTo,
- intresultCode,StringresultData,Bundlemap,
- StringrequiredPermission,booleanserialized,
- booleansticky)throwsRemoteException
- {
- Parceldata=Parcel.obtain();
- Parcelreply=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();
- intres=reply.readInt();
- reply.recycle();
- data.recycle();
- returnres;
- }
- ......
- }
Step 4.ctivityManagerService.broadcastIntent
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- publicfinalintbroadcastIntent(IApplicationThreadcaller,
- Intentintent,StringresolvedType,IIntentReceiverresultTo,
- intresultCode,StringresultData,Bundlemap,
- StringrequiredPermission,booleanserialized,booleansticky){
- synchronized(this){
- intent=verifyBroadcastLocked(intent);
- finalProcessRecordcallerApp=getRecordForAppLocked(caller);
- finalintcallingPid=Binder.getCallingPid();
- finalintcallingUid=Binder.getCallingUid();
- finallongorigId=Binder.clearCallingIdentity();
- intres=broadcastIntentLocked(callerApp,
- callerApp!=null?callerApp.info.packageName:null,
- intent,resolvedType,resultTo,
- resultCode,resultData,map,requiredPermission,serialized,
- sticky,callingPid,callingUid);
- Binder.restoreCallingIdentity(origId);
- returnres;
- }
- }
- ......
- }
Step 5.ActivityManagerService.broadcastIntentLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
[java] view plain copy- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalintbroadcastIntentLocked(ProcessRecordcallerApp,
- StringcallerPackage,Intentintent,StringresolvedType,
- IIntentReceiverresultTo,intresultCode,StringresultData,
- Bundlemap,StringrequiredPermission,
- booleanordered,booleansticky,intcallingPid,intcallingUid){
- intent=newIntent(intent);
- ......
- //Figureoutwhoallwillreceivethisbroadcast.
- Listreceivers=null;
- List<BroadcastFilter>registeredReceivers=null;
- try{
- if(intent.getComponent()!=null){
- ......
- }else{
- ......
- registeredReceivers=mReceiverResolver.queryIntent(intent,resolvedType,false);
- }
- }catch(RemoteExceptionex){
- ......
- }
- finalbooleanreplacePending=
- (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING)!=0;
- intNR=registeredReceivers!=null?registeredReceivers.size():0;
- if(!ordered&&NR>0){
- //Ifwearenotserializingthisbroadcast,thensendthe
- //registeredreceiversseparatelysotheydon'twaitforthe
- //componentstobelaunched.
- BroadcastRecordr=newBroadcastRecord(intent,callerApp,
- callerPackage,callingPid,callingUid,requiredPermission,
- registeredReceivers,resultTo,resultCode,resultData,map,
- ordered,sticky,false);
- ......
- booleanreplaced=false;
- if(replacePending){
- for(inti=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;
- }
- ......
- }
- ......
- }
- //Figureoutwhoallwillreceivethisbroadcast.
- Listreceivers=null;
- List<BroadcastFilter>registeredReceivers=null;
- try{
- if(intent.getComponent()!=null){
- ......
- }else{
- ......
- registeredReceivers=mReceiverResolver.queryIntent(intent,resolvedType,false);
- }
- }catch(RemoteExceptionex){
- ......
- }
继续往下看:
[java] view plain copy- finalbooleanreplacePending=
- (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING)!=0;
再接着往下看:
[java] view plain copy- intNR=registeredReceivers!=null?registeredReceivers.size():0;
- if(!ordered&&NR>0){
- //Ifwearenotserializingthisbroadcast,thensendthe
- //registeredreceiversseparatelysotheydon'twaitforthe
- //componentstobelaunched.
- BroadcastRecordr=newBroadcastRecord(intent,callerApp,
- callerPackage,callingPid,callingUid,requiredPermission,
- registeredReceivers,resultTo,resultCode,resultData,map,
- ordered,sticky,false);
- ......
- booleanreplaced=false;
- if(replacePending){
- for(inti=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文件中:
[java] view plain copy- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalvoidscheduleBroadcastsLocked(){
- ......
- 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函数来真正处理这个消息:
[java] view plain copy- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- finalHandlermHandler=newHandler(){
- publicvoidhandleMessage(Messagemsg){
- switch(msg.what){
- ......
- caseBROADCAST_INTENT_MSG:{
- ......
- processNextBroadcast(true);
- }break;
- ......
- }
- }
- }
- ......
- }
Step 8.ActivityManagerService.processNextBroadcast
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
[java] view plain copy- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalvoidprocessNextBroadcast(booleanfromMsg){
- synchronized(this){
- BroadcastRecordr;
- ......
- if(fromMsg){
- mBroadcastsScheduled=false;
- }
- //First,deliveranynon-serializedbroadcastsrightaway.
- while(mParallelBroadcasts.size()>0){
- r=mParallelBroadcasts.remove(0);
- ......
- finalintN=r.receivers.size();
- ......
- for(inti=0;i<N;i++){
- Objecttarget=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文件中:
[java] view plain copy- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- privatefinalvoiddeliverToRegisteredReceiverLocked(BroadcastRecordr,
- BroadcastFilterfilter,booleanordered){
- booleanskip=false;
- if(filter.requiredPermission!=null){
- ......
- }
- if(r.requiredPermission!=null){
- ......
- }
- if(!skip){
- //Ifthisisnotbeingsentasanorderedbroadcast,thenwe
- //don'twanttotouchthefieldsthatkeeptrackofthecurrent
- //stateoforderedbroadcasts.
- if(ordered){
- ......
- }
- try{
- ......
- performReceiveLocked(filter.receiverList.app,filter.receiverList.receiver,
- newIntent(r.intent),r.resultCode,
- r.resultData,r.resultExtras,r.ordered,r.initialSticky);
- ......
- }catch(RemoteExceptione){
- ......
- }
- }
- }
- ......
- }
Step 10.ActivityManagerService.performReceiveLocked
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
[java] view plain copy- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- staticvoidperformReceiveLocked(ProcessRecordapp,IIntentReceiverreceiver,
- Intentintent,intresultCode,Stringdata,Bundleextras,
- booleanordered,booleansticky)throwsRemoteException{
- //Sendtheintenttothereceiverasynchronouslyusingone-waybindercalls.
- if(app!=null&&app.thread!=null){
- //Ifwehaveanappthread,dothecallthroughthatsoitis
- //correctlyorderedwithotherone-waycalls.
- 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文件中:
- classApplicationThreadProxyimplementsIApplicationThread{
- ......
- publicvoidscheduleRegisteredReceiver(IIntentReceiverreceiver,Intentintent,
- intresultCode,StringdataStr,Bundleextras,booleanordered,booleansticky)
- throwsRemoteException{
- Parceldata=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文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalclassApplicationThreadextendsApplicationThreadNative{
- ......
- //Thisfunctionexiststomakesureallreceiverdispatchingis
- //correctlyordered,sincetheseareone-waycallsandthebinderdriver
- //appliestransactionorderingperobjectforsuchcalls.
- publicvoidscheduleRegisteredReceiver(IIntentReceiverreceiver,Intentintent,
- intresultCode,StringdataStr,Bundleextras,booleanordered,
- booleansticky)throwsRemoteException{
- receiver.performReceive(intent,resultCode,dataStr,extras,ordered,sticky);
- }
- ......
- }
- ......
- }
Step 13.InnerReceiver.performReceive
这个函数定义在frameworks/base/core/java/android/app/LoadedApk.java文件中:
- finalclassLoadedApk{
- ......
- staticfinalclassReceiverDispatcher{
- finalstaticclassInnerReceiverextendsIIntentReceiver.Stub{
- ......
- publicvoidperformReceive(Intentintent,intresultCode,
- Stringdata,Bundleextras,booleanordered,booleansticky){
- LoadedApk.ReceiverDispatcherrd=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文件中:
[java] view plain copy- finalclassLoadedApk{
- ......
- staticfinalclassReceiverDispatcher{
- ......
- publicvoidperformReceive(Intentintent,intresultCode,
- Stringdata,Bundleextras,booleanordered,booleansticky){
- ......
- Argsargs=newArgs();
- 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文件中:
[java] view plain copy- finalclassLoadedApk{
- ......
- staticfinalclassReceiverDispatcher{
- ......
- finalclassArgsimplementsRunnable{
- ......
- publicvoidrun(){
- BroadcastReceiverreceiver=mReceiver;
- ......
- Intentintent=mCurIntent;
- ......
- try{
- ClassLoadercl=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(Exceptione){
- ......
- }
- ......
- }
- ......
- }
- ......
- }
- ......
- }
有了这个ReceiverDispatcher实例之后,就可以调用它的onReceive函数把这个广播分发给它处理了。
Step 17. BroadcastReceiver.onReceive
这个函数定义Android系统中的广播(Broadcast)机制简要介绍和学习计划一文中所介绍的Android应用程序Broadcast的工程目录下的src/shy/luo/broadcast/MainActivity.java文件中:
[java] view plain copy- publicclassMainActivityextendsActivityimplementsOnClickListener{
- ......
- privateBroadcastReceivercounterActionReceiver=newBroadcastReceiver(){
- publicvoidonReceive(Contextcontext,Intentintent){
- intcounter=intent.getIntExtra(CounterService.COUNTER_VALUE,0);
- Stringtext=String.valueOf(counter);
- counterText.setText(text);
- Log.i(LOG_TAG,"Receivecounterevent");
- }
- }
- ......
- }
至此,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)机制简要介绍和学习计划一文中。
更多相关文章
- C语言函数的递归(上)
- Android(安卓)Window类解析
- 新版NDK环境搭建(免Cygwin,超级快)
- Android(安卓)自定义View - 启航 一般View定义
- android.widget.Toast——快显信息
- Android(安卓)ImageSpan与TextView中的text居中对齐问题解决(无论
- lambda表达式介绍以及Android(安卓)Studio引入lambda
- [置顶] Android(安卓)Launcher全面剖析
- getevent工具和Android中inputevent的分析