BroadcastReceiver的工作流程

1.广播的基本使用

类继承 BroadcastReceiver,onReceive回调中处理业务逻辑
intent.getAction来匹配之前写的action等。

静态:manifest里面注册,通过intent匹配
动态: a. new BroadcastReceiver,
      b. new IntentFilter,
      c. intentfilter.addAction("匹配规则")
      d. registerReceiver
      e. unregisterReceiver

2.广播的工作流程

2.1 广播的注册过程

2.1.1 静态注册:pms(PackageManagerService)来完成解析和注册,四大组件均是pms来完成解析和注册

public class PackageManagerService extends IPackageManager.Stub  implements PackageSender {

mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
                            android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
                            new BroadcastReceiver() {
                                @Override
                                public void onReceive(Context context, Intent intent) {
                                    final Message msg = mHandler                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
                                    msg.arg1 = verificationId;
                                    mHandler.sendMessageDelayed(msg, getVerificationTimeout());
                                }
                            }, null, 0, null, null);
                    mArgs = null;
                }

实际上底层还是通过binder和handler

2.1.2 动态注册:

//入口是在ContextWrap的registerReceiver中。
@Override
public Intent registerReceiver(
    BroadcastReceiver receiver, IntentFilter filter) {
    return mBase.registerReceiver(receiver, filter);
}

具体实现则是在ContextImpl(路径:Android/sdk/sources/android-26/android/app)

//实际上是进程间通信的过程,broadCastReceiver无法直接跨进程传递,需要通过binder进行传递。而IIntentReceiver则是作为一个中转层
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
        IntentFilter filter, String broadcastPermission,
        Handler scheduler, Context context, int flags) {
    IIntentReceiver rd = null;//这里是binder的接口。
    if (receiver != null) {
        if (mPackageInfo != null && context != null) {
            if (scheduler == null) {
                scheduler = mMainThread.getHandler();
            }

            rd = mPackageInfo.getReceiverDispatcher(
    //通过广播和context和handler和Instrumentation的转换,获取到iIntentReceiver,取出rd的方法

                receiver, context, scheduler,
                mMainThread.getInstrumentation(), true);
        } else {
            if (scheduler == null) {
                scheduler = mMainThread.getHandler();
            }
            rd = new LoadedApk.ReceiverDispatcher(
          //主要的存放的方法,intentReceiver的具体实现如下图                        
      receiver, context, scheduler, null, true).getIIntentReceiver();
        }
    }
    try {
        final Intent intent =
        //核心注册代码,activityManager得到服务
        //实际上是在ActivityManagerService中调用registerReceiver
              ActivityManager.getService().registerReceiver(
              mMainThread.getApplicationThread(), 
              mBasePackageName, rd, filter,
              broadcastPermission, userId, flags);
        if (intent != null) {
            intent.setExtrasClassLoader(getClassLoader());
            intent.prepareToEnterProcess();
        }
        return intent;
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
}

public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
        Context context, Handler handler,
        Instrumentation instrumentation, boolean registered) {
    synchronized (mReceivers) {
        LoadedApk.ReceiverDispatcher rd = null;
        ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;//通过键值对的形式去存context和BroadCastReceiver。
        if (registered) {
            map = mReceivers.get(context);
            if (map != null) {
                rd = map.get(r);
            }
        }
        if (rd == null) {
            rd = new ReceiverDispatcher(r, context, handler,
                    instrumentation, registered);
            if (registered) {
                if (map == null) {
                    map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
                    mReceivers.put(context, map);
                }
                map.put(r, rd);
            }
        } else {
            rd.validate(context, handler);
        }
        rd.mForgotten = false;
        return rd.getIIntentReceiver();
    }
}

intentReceiver的具体实现

真正的注册代码核心(AMS中的registerReceiver中)
最终将远程的innerReceiver对象以及IntentFilter对象存储起来

mRegisteredReceivers.put(receiver.asBinder(), rl);
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
                permission, callingUid, userId, instantApp, visibleToInstantApps);
rl.add(bf);
mReceiverResolver.addFilter(bf);

也就是说,动态注册的过程如下:
Activity的registerReceiver==>
ContextWrap的registerReceiver==>
ContextImpl的registerReceiverInternal()==>
LoadedApk的getReceiverDispatcher()获取IIntentReceiver==>
ActivityManager的registerReceiver。

2.2 广播发送和接收的过程

2.2.1 发送

依然是从ContextWrapper的sendBroadcast开始,实现为ContextImp的sendBroadcast。

@Override
public void sendBroadcast(Intent intent) {
    warnIfCallingFromSystemProcess();
    String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    try {
        intent.prepareToLeaveProcess(this);
      //异步向ams发送广播
        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();
    }
}

AMS发送广播代码

 public final int broadcastIntent(IApplicationThread caller,
        Intent intent, String resolvedType, IIntentReceiver resultTo,
        int resultCode, String resultData, Bundle resultExtras,
        String[] requiredPermissions, int appOp, Bundle bOptions,
        boolean serialized, boolean sticky, int userId) {
    enforceNotIsolatedCaller("broadcastIntent");
    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();
        //核心代码        
        //广播默认不发送给已经停止的应用
        //intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);

        int res = broadcastIntentLocked(callerApp,
                callerApp != null ? callerApp.info.packageName : null,
                intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
                requiredPermissions, appOp, bOptions, serialized, sticky,
                callingPid, callingUid, userId);
        Binder.restoreCallingIdentity(origId);
        return res;
    }
}



final int broadcastIntentLocked() {   
  final BroadcastQueue queue = broadcastQueueForIntent(intent);
  BroadcastRecord r = new BroadcastRecord();
        final boolean replaced = replacePending
                && (queue.replaceParallelBroadcastLocked(r) != null);
          if (!replaced) {
            //排序
            queue.enqueueParallelBroadcastLocked(r);
            //发送过程
            queue.scheduleBroadcastsLocked();
        }
        registeredReceivers = null;
        NR = 0;
    }

BroadCastQueue的scheduleBroadcastsLocked方法

public void scheduleBroadcastsLocked() {
    //Set when we current have a BROADCAST_INTENT_MSG in flight
    if (mBroadcastsScheduled) {
        return;
    }
//通过handler发送一个Broadcast_intent_msg           
 mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
    mBroadcastsScheduled = 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");
                processNextBroadcast(true);
            } break;



final void processNextBroadcast(boolean fromMsg) {
        while (mParallelBroadcasts.size() > 0) {
            r = mParallelBroadcasts.remove(0);
            r.dispatchTime = SystemClock.uptimeMillis();
            r.dispatchClockTime = System.currentTimeMillis();
            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
                    System.identityHashCode(r));
                Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
                    System.identityHashCode(r));
            }

            final int N = r.receivers.size();
            for (int i=0; i<N; i++) {
                Object target = r.receivers.get(i);
                deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
            }
            addBroadcastToHistoryLocked(r);
        }
}

deliverToRegisteredReceiverLocked()内部调performReceiveLocked()方法完成具体的发送。

也就是说 整个流程为:
ContextWrapper的sendBroadcast()==>
ContextImp的sendBroadcast()==>
AMS的broadcastIntent()==>
AMS的broadcastIntentLocked==>
BroadCastQueue的scheduleBroadcastsLocked()==>
processNextBroadcast()==>
deliverToRegisteredReceiverLocked()==>
performReceiveLocked()==>
scheduleRegisteredReceiver==>
ApplicationThread(ActivityThread的内部类)==>

//ActivityThread的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);
        receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
                sticky, sendingUser);
      //内部则是LoadApk的ReceiverDispatcher类的performReceive方法
    }

而performReceive内部则是调用

ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
intent.prepareToEnterProcess();
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
receiver.onReceive(mContext, intent);

完成整个广播的注册

igding wechat
2018 依计行事 持续精进
坚持原创技术分享,您的支持将鼓励我继续创作!