广播的发送和接收过程

之前整理了广播的动态注册过程《广播的注册过程》,本文接着梳理广播的发送和接收过程,广播的发送同样是调用到ContextWrapper类的sendBroadcast方法:

Context mBase;

@Override
public void sendBroadcast(Intent intent) {
    mBase.sendBroadcast(intent);
}

由上面的代码可知,ContextWrapper也没有做任何真正发送广播的操作,而是将具体工作转嫁给了ContextImpl类型的mBase,调用了mBase的sendBroadcast方法:

@Override
public void sendBroadcast(Intent intent) {
   warnIfCallingFromSystemProcess();
   String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
   try {
       intent.prepareToLeaveProcess(this);

	   //注释1 跨进程调用
       ActivityManager.getService().broadcastIntent(
               mMainThread.getApplicationThread(), intent, resolvedType, null,
               Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
               getUserId());
               
   } catch (RemoteException e) {
       throw e.rethrowFromSystemServer();
   }
}

在注释1处ActivityManager.getService()获取到的是AMS的一个Binder代理,所以最终调用到了AMS的broadcastIntent方法,在broadcastIntent里又调用了broadcastIntentLocked方法:

@GuardedBy("this")
final int broadcastIntentLocked(ProcessRecord callerApp,
        String callerPackage, Intent intent, String resolvedType,
        IIntentReceiver resultTo, int resultCode, String resultData,
        Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
        boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
        
        ...........................

  //注释2
  if ((receivers != null && receivers.size() > 0)
                 || resultTo != null) {
        BroadcastQueue queue = broadcastQueueForIntent(intent);
        BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
                callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
                requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
                resultData, resultExtras, ordered, sticky, false, userId);

        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
                + ": prev had " + queue.mOrderedBroadcasts.size());
        if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
                "Enqueueing broadcast " + r.intent.getAction());

        final BroadcastRecord oldRecord =
                replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
        if (oldRecord != null) {
            // Replaced, fire the result-to receiver.
            if (oldRecord.resultTo != null) {
                final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
                try {
                    oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
                            oldRecord.intent,
                            Activity.RESULT_CANCELED, null, null,
                            false, false, oldRecord.userId);
                } catch (RemoteException e) {
                    Slog.w(TAG, "Failure ["
                            + queue.mQueueName + "] sending broadcast result of "
                            + intent, e);

                }
            }
        } else {
            queue.enqueueOrderedBroadcastLocked(r);

			//注释3
            queue.scheduleBroadcastsLocked();
        }
    } else {
        // There was nobody interested in the broadcast, but we still want to record
        // that it happened.
        if (intent.getComponent() == null && intent.getPackage() == null
                && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
            // This was an implicit broadcast... let's record it for posterity.
            addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
        }
    }

    return ActivityManager.BROADCAST_SUCCESS;
}

注释2处的receivers列表里存储了所有合法的广播接收者信息(包括有序和无序),在注释3处调用了BroadcastQueue的scheduleBroadcastsLocked方法:

    public void scheduleBroadcastsLocked() {
        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["
                + mQueueName + "]: current="
                + mBroadcastsScheduled);

        if (mBroadcastsScheduled) {
            return;
        }

		//注释4
        mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
        
        mBroadcastsScheduled = true;
    }

在注释4处发送了一个handler消息,由于mHandler的类型是BroadcastHandler,那消息的处理肯定在BroadcastHandler的handleMessage方法里,BroadcastHandler是BroadcastQueue的一个内部类,下面看下BroadcastHandler的相关源码:

private final class BroadcastHandler extends Handler {
    public BroadcastHandler(Looper looper) {
        super(looper, null, true);
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case BROADCAST_INTENT_MSG: {
                if (DEBUG_BROADCAST) Slog.v(
                        TAG_BROADCAST, "Received BROADCAST_INTENT_MSG");

	 			//注释5
                processNextBroadcast(true);
            } break;
            case BROADCAST_TIMEOUT_MSG: {
                synchronized (mService) {
                    broadcastTimeoutLocked(true);
                }
            } break;
        }
    }
}

从注释5处可知,这是处理注释4处发送的handler消息BROADCAST_INTENT_MSG的地方,此处调用到了BroadcastQueue的processNextBroadcast方法:

final void processNextBroadcast(boolean fromMsg) {
    synchronized (mService) {
		
		//注释6
        processNextBroadcastLocked(fromMsg, false);
    }
}

在注释6处又调用到了processNextBroadcastLocked方法:

final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
        BroadcastRecord r;

		.................

        if (fromMsg) {
            mBroadcastsScheduled = false;
        }

        // First, deliver any non-serialized broadcasts right away.
        while (mParallelBroadcasts.size() > 0) {//注释7
            r = mParallelBroadcasts.remove(0);//注释8
       
              .................
               
            for (int i=0; i<N; i++) {
                Object target = r.receivers.get(i);
                
              .................
              
                //注释9
                deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
            }
            .................
       }
       .................
}

mParallelBroadcasts是存储无序广播信息的列表,在注释7和8处遍历无序广播列表,并从列表中逐个取出BroadcastRecord类型的r对象(记录着广播信息),在注释9处把广播信息发送给对应的广播接收者。deliverToRegisteredReceiverLocked方法的源码如下:

private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
           BroadcastFilter filter, boolean ordered, int index) {
           
	.................
	
	 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
	                       new Intent(r.intent), r.resultCode, r.resultData,
	                       r.resultExtras, r.ordered, r.initialSticky, r.userId);
	
	
	.................
	
}

上述代码中又继续调用了performReceiveLocked方法:

void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
          Intent intent, int resultCode, String data, Bundle extras,
          boolean ordered, boolean sticky, int sendingUser) throws RemoteException {

	.................

		  //注释10
	      if (app != null) {
	          if (app.thread != null) {
	              try {
	                  app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
	                          data, extras, ordered, sticky, sendingUser, 
	              }               
	.................
		       }
	        }
	         
	.................
}

在注释10处的app.thread是ApplicationThread,看下scheduleRegisteredReceiver方法:

public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
         int resultCode, String dataStr, Bundle extras, boolean ordered,
         boolean sticky, int sendingUser, int processState) throws RemoteException {
     updateProcessState(processState, false);

	 //注释11
     receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
             sticky, sendingUser);
 }

在注释11处的地方又继续调用了LoadedApk.ReceiverDispatcher.InnerReceiver类型的receiver的performReceive方法,下面继续跟下源码:

static final class ReceiverDispatcher {
      final static class InnerReceiver extends IIntentReceiver.Stub {
      
       .................
      
          InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
              mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
              mStrongRef = strong ? rd : null;
          }
          
          @Override
          public void performReceive(Intent intent, int resultCode, String data,
                  Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
                  
              final LoadedApk.ReceiverDispatcher rd;
              
              .................
              //注释12
              if (rd != null) {
                  rd.performReceive(intent, resultCode, data, extras,
                          ordered, sticky, sendingUser);
              } 
         
	    .................
}

在注释12处调用了rd的performReceive方法,rd是LoadedApk.ReceiverDispatcher类型的,下面继续看下performReceive方法源码:

public void performReceive(Intent intent, int resultCode, String data,
        Bundle extras, boolean ordered, boolean sticky, int sendingUser) {


	//注释13
    final Args args = new Args(intent, resultCode, data, extras, ordered,
            sticky, sendingUser);
            
	.................

	//注释14
    if (intent == null || !mActivityThread.post(args.getRunnable())) {
        if (mRegistered && ordered) {
            IActivityManager mgr = ActivityManager.getService();
            if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                    "Finishing sync broadcast to " + mReceiver);
            args.sendFinished(mgr);
        }
    }
}

在注释13处,将广播的intent等相关信息都封装到了Args对象里面,在注释14处通过Handler类型的mActivityThread(就是ActivityThread中的H)的post方法,将args.getRunnable()对象post到主线程的消息队列中,最终会执行到Args里的Runnable的run方法里:

static final class ReceiverDispatcher {

	.................

	 final BroadcastReceiver mReceiver;
 
	 .................
 
	   final class Args extends BroadcastReceiver.PendingResult {
	   .................
	       public final Runnable getRunnable() {
	                return () -> {
	                .................
						//注释15
	                    final BroadcastReceiver receiver = mReceiver;
	                        try {
	                        ClassLoader cl = mReceiver.getClass().getClassLoader();
	                        intent.setExtrasClassLoader(cl);
	                        intent.prepareToEnterProcess();
	                        setExtrasClassLoader(cl);
	                        receiver.setPendingResult(this);
	
							//注释16
	                        receiver.onReceive(mContext, intent);
	                    }
	                    .................
	               }
	           }
	     }
 }

在注释15处的receiver赋值为之前保存的App本地进程的BroadcastReceiver对象,在注释16处调用了receiver.onReceive方法,这样在App里注册的对应广播接收者就接收到广播消息了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值