Android应用程序发送广播(sendBroadcast)的过程分析(1)

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

 
 
  1. public class CounterService extends Service implements ICounterService {     
  2.     ......    
  3.    
  4.     public void startCounter(int initVal) {     
  5.         AsyncTask<Integer, Integer, Integer> task = new AsyncTask<Integer, Integer, Integer>() {         
  6.             @Override     
  7.             protected Integer doInBackground(Integer... vals) {     
  8.                 ......     
  9.             }     
  10.    
  11.             @Override      
  12.             protected void onProgressUpdate(Integer... values) {     
  13.                 super.onProgressUpdate(values);     
  14.    
  15.                 int counter = values[0];     
  16.    
  17.                 Intent intent = new Intent(BROADCAST_COUNTER_ACTION);     
  18.                 intent.putExtra(COUNTER_VALUE, counter);     
  19.    
  20.                 sendBroadcast(intent);     
  21.             }     
  22.    
  23.             @Override     
  24.             protected void onPostExecute(Integer val) {     
  25.                 ......    
  26.             }     
  27.    
  28.         };     
  29.    
  30.         task.execute(0);         
  31.     }     
  32.    
  33.     ......   
  34. }   

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

 
 
  1. public class ContextWrapper extends Context {   
  2.     Context mBase;   
  3.    
  4.     ......   
  5.    
  6.     @Override   
  7.     public void sendBroadcast(Intent intent) {   
  8.         mBase.sendBroadcast(intent);   
  9.     }   
  10.    
  11.     ......   
  12.    
  13. }   

        这里的成员变量mBase是一个ContextImpl实例,这里只简单地调用ContextImpl.sendBroadcast进一行操作。

         Step 2. ContextImpl.sendBroadcast

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

 
 
  1. class ContextImpl extends Context {   
  2.     ......   
  3.    
  4.     @Override   
  5.     public void sendBroadcast(Intent intent) {   
  6.         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());   
  7.         try {   
  8.             ActivityManagerNative.getDefault().broadcastIntent(   
  9.                 mMainThread.getApplicationThread(), intent, resolvedType, null,   
  10.                 Activity.RESULT_OK, nullnullnullfalsefalse);   
  11.         } catch (RemoteException e) {   
  12.         }   
  13.     }   
  14.    
  15.     ......   
  16.    
  17. }   

        这里的resolvedType表示这个Intent的MIME类型,我们没有设置这个Intent的MIME类型,因此,这里的resolvedType为null。接下来就调用ActivityManagerService的远程接口ActivityManagerProxy把这个广播发送给ActivityManagerService了。

        Step 3. ActivityManagerProxy.broadcastIntent

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

 
 
  1. class ActivityManagerProxy implements IActivityManager   
  2. {   
  3.     ......   
  4.    
  5.     public int broadcastIntent(IApplicationThread caller,   
  6.         Intent intent, String resolvedType,  IIntentReceiver resultTo,   
  7.         int resultCode, String resultData, Bundle map,   
  8.         String requiredPermission, boolean serialized,   
  9.         boolean sticky) throws RemoteException   
  10.     {   
  11.         Parcel data = Parcel.obtain();   
  12.         Parcel reply = Parcel.obtain();   
  13.         data.writeInterfaceToken(IActivityManager.descriptor);   
  14.         data.writeStrongBinder(caller != null ? caller.asBinder() : null);   
  15.         intent.writeToParcel(data, 0);   
  16.         data.writeString(resolvedType);   
  17.         data.writeStrongBinder(resultTo != null ? resultTo.asBinder() : null);   
  18.         data.writeInt(resultCode);   
  19.         data.writeString(resultData);   
  20.         data.writeBundle(map);   
  21.         data.writeString(requiredPermission);   
  22.         data.writeInt(serialized ? 1 : 0);   
  23.         data.writeInt(sticky ? 1 : 0);   
  24.         mRemote.transact(BROADCAST_INTENT_TRANSACTION, data, reply, 0);   
  25.         reply.readException();   
  26.         int res = reply.readInt();   
  27.         reply.recycle();   
  28.         data.recycle();   
  29.         return res;   
  30.     }   
  31.    
  32.     ......   
  33.    
  34. }   

         这里的实现比较简单,把要传递的参数封装好,然后通过Binder驱动程序进入到ActivityManagerService的broadcastIntent函数中。

         Step 4. ctivityManagerService.broadcastIntent

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

 
 
  1. public final class ActivityManagerService extends ActivityManagerNative   
  2.         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {   
  3.     ......   
  4.    
  5.     public final int broadcastIntent(IApplicationThread caller,   
  6.             Intent intent, String resolvedType, IIntentReceiver resultTo,   
  7.             int resultCode, String resultData, Bundle map,   
  8.             String requiredPermission, boolean serialized, boolean sticky) {   
  9.         synchronized(this) {   
  10.             intent = verifyBroadcastLocked(intent);   
  11.    
  12.             final Proce***ecord callerApp = getRecordForAppLocked(caller);   
  13.             final int callingPid = Binder.getCallingPid();   
  14.             final int callingUid = Binder.getCallingUid();   
  15.             final long origId = Binder.clearCallingIdentity();   
  16.             int res = broadcastIntentLocked(callerApp,   
  17.                 callerApp != null ? callerApp.info.packageName : null,   
  18.                 intent, resolvedType, resultTo,   
  19.                 resultCode, resultData, map, requiredPermission, serialized,   
  20.                 sticky, callingPid, callingUid);   
  21.             Binder.restoreCallingIdentity(origId);   
  22.             return res;   
  23.         }   
  24.     }   
  25.    
  26.     ......   
  27. }   
 

        这里调用broadcastIntentLocked函数来进一步处理。

         Step 5. ActivityManagerService.broadcastIntentLocked

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

 
 
  1. public final class ActivityManagerService extends ActivityManagerNative   
  2.         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {   
  3.     ......   
  4.    
  5.     private final int broadcastIntentLocked(Proce***ecord callerApp,   
  6.             String callerPackage, Intent intent, String resolvedType,   
  7.             IIntentReceiver resultTo, int resultCode, String resultData,   
  8.             Bundle map, String requiredPermission,   
  9.             boolean ordered, boolean sticky, int callingPid, int callingUid) {   
  10.         intent = new Intent(intent);   
  11.    
  12.         ......   
  13.    
  14.         // Figure out who all will receive this broadcast.   
  15.         List receivers = null;   
  16.         List<BroadcastFilter> registeredReceivers = null;   
  17.         try {   
  18.             if (intent.getComponent() != null) {   
  19.                 ......   
  20.             } else {   
  21.                 ......   
  22.                 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);   
  23.             }   
  24.         } catch (RemoteException ex) {   
  25.             ......   
  26.         }   
  27.    
  28.         final boolean replacePending =   
  29.             (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;   
  30.    
  31.         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;   
  32.         if (!ordered && NR > 0) {   
  33.             // If we are not serializing this broadcast, then send the   
  34.             // registered receivers separately so they don't wait for the   
  35.             // components to be launched.   
  36.             BroadcastRecord r = new BroadcastRecord(intent, callerApp,   
  37.                 callerPackage, callingPid, callingUid, requiredPermission,   
  38.                 registeredReceivers, resultTo, resultCode, resultData, map,   
  39.                 ordered, sticky, false);   
  40.             ......   
  41.             boolean replaced = false;   
  42.             if (replacePending) {   
  43.                 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {   
  44.                     if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {   
  45.                         ......   
  46.                         mParallelBroadcasts.set(i, r);   
  47.                         replaced = true;   
  48.                         break;   
  49.                     }   
  50.                 }   
  51.             }   
  52.    
  53.             if (!replaced) {   
  54.                 mParallelBroadcasts.add(r);   
  55.    
  56.                 scheduleBroadcastsLocked();   
  57.             }   
  58.    
  59.             registeredReceivers = null;   
  60.             NR = 0;   
  61.         }   
  62.    
  63.         ......   
  64.    
  65.     }   
  66.    
  67.     ......   
  68. }   

    这个函数首先是根据intent找出相应的广播接收器:

 
 
  1.    // Figure out who all will receive this broadcast.   
  2.    List receivers = 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 (RemoteException ex) {   
  12. ......   
  13.    }   

     回忆一下前面一篇文章Android应用程序注册广播接收器(registerReceiver)的过程分析中的Step 6(ActivityManagerService.registerReceiver)中,我们将一个filter类型为BROADCAST_COUNTER_ACTION类型的BroadcastFilter实例保存在了ActivityManagerService的成员变量mReceiverResolver中,这个BroadcastFilter实例包含了我们所注册的广播接收器,这里就通过mReceiverResolver.queryIntent函数将这个BroadcastFilter实例取回来。由于注册一个广播类型的接收器可能有多个,所以这里把所有符合条件的的BroadcastFilter实例放在一个List中,然后返回来。在我们这个场景中,这个List就只有一个BroadcastFilter实例了,就是MainActivity注册的那个广播接收器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值