Skip to content

Latest commit

 

History

History
370 lines (319 loc) · 12.7 KB

广播启动过程.md

File metadata and controls

370 lines (319 loc) · 12.7 KB

1 简介

广播的注册分为静态注册和动态注册,主要分析动态注册,可以从三个方面来分析;

  • 广播的注册
  • 广播的发送
  • 广播的处理

2 原理

2.1 广播的注册

ContextWrapper#registerReceiver()

@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
     //mBase -> ContextImpl
     return mBase.registerReceiver(receiver, filter);
}

ContextImpl#registerReceiver()

registerReceiver() 有多个重载函数,最终调用到以下函数。

private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId, IntentFilter filter, String broadcastPermission, Handler scheduler, Context context) {
    IIntentReceiver rd = null;
    if (receiver != null) {
        if (mPackageInfo != null && context != null) {
            if (scheduler == null) {
                //将 scheduler 赋值为 主线程的 Handler
                scheduler = mMainThread.getHandler();
            }
            //代码一:获取 IIntentReceiver对象 mPackageInfo -> LoasedApk 类型
            rd = mPackageInfo.getReceiverDispatcher(
                receiver, context, scheduler,
                mMainThread.getInstrumentation(), true);
        } else {
            if (scheduler == null) {
                scheduler = mMainThread.getHandler();
            }
            rd = new LoadedApk.ReceiverDispatcher(
                  receiver, context, scheduler, null, true).getIIntentReceiver();
        }
    }
    try {
        //代码二:调用 ActivityManagerProxy(AMP) 的 registerReceiver
        return ActivityManagerNative.getDefault().registerReceiver(
                mMainThread.getApplicationThread(), mBasePackageName,
                rd, filter, broadcastPermission, userId);
    } catch (RemoteException e) {
        return null;
    }
}

代码一:LoadedApk

  static final class ReceiverDispatcher {
        //显然 IIntentReceiver 是一个 Binder 接口,跨进程通信
        final static class InnerReceiver extends IIntentReceiver.Stub {
            final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
            final LoadedApk.ReceiverDispatcher mStrongRef;

            InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
                mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
                mStrongRef = strong ? rd : null;
            }

代码二:ActivityManagerService#registerReceiver()

ActivityManagerNative.getDefault() 最终会调用 ActivityManagerService#registerReceiver() 方法。

public Intent registerReceiver(...) {
        ...
        ProcessRecord callerApp = null;
        ...
        synchronized(this) {
            if (caller != null) {
            //获取调用者的进程信息
            callerApp = getRecordForAppLocked(caller);
            ...
            //获取 IntentFilter 中的 actions 信息
            Iterator<String> actions = filter.actionsIterator();
            if (actions == null) {
                ArrayList<String> noAction = new ArrayList<String>(1);
                noAction.add(null);
                actions = noAction.iterator();
            }
            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
            while (actions.hasNext()) {
                String action = actions.next();
                for (int id : userIds) {
                    //从mStickyBroadcasts中查看用户的sticky Intent
                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
                    if (stickies != null) {
                        ArrayList<Intent> intents = stickies.get(action);
                        if (intents != null) {
                            if (stickyIntents == null) {
                                stickyIntents = new ArrayList<Intent>();
                            }                           
                            //把粘性广播添加到列表中
                            stickyIntents.addAll(intents);
                        }
                    }
                }
            }
        }
        ...


        synchronized (this) {
            ...
            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
            if (rl == null) {
                //对于未注册的广播,则创建接受者队列
                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
                        userId, receiver);
                if (rl.app != null) {
                    final int totalReceiversForApp = rl.app.receivers.size();
                    if (totalReceiversForApp >= MAX_RECEIVERS_ALLOWED_PER_APP) {
                        throw new IllegalStateException("Too many receivers, total of "
                                + totalReceiversForApp + ", registered for pid: "
                                + rl.pid + ", callerPackage: " + callerPackage);
                    }
                    rl.app.receivers.add(rl);
                } else {
                    try {
                        receiver.asBinder().linkToDeath(rl, 0);
                    } catch (RemoteException e) {
                        return sticky;
                    }
                    rl.linkedToDeath = true;
                }
                //新建的接受者队列,添加到已注册广播队列
                mRegisteredReceivers.put(receiver.asBinder(), rl);
            }
            ...
            //创建BroadcastFilter,并添加到接受者队列
            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
                    permission, callingUid, userId, instantApp, visibleToInstantApps);
            if (rl.containsFilter(filter)) {
              ...
            } else {
                ...
                //新建的BroadcastFilter,添加到mReceiverResolver队列中
                mReceiverResolver.addFilter(bf);
            }
            ...
            return sticky;
        }
    }

其实就是用来记录着所有已经注册的广播。

2.2 广播的发送

发送广播其实就是调用 sendBroadcast(),在 ContextImpl 里面。

ContextImpl#sendBroadcast()

public void sendBroadcast(Intent intent) {
    warnIfCallingFromSystemProcess();
    String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    try {
        ...
        // 调用 AMP.broadcastIntent 
        ActivityManagerNative.getDefault().broadcastIntent(
                mMainThread.getApplicationThread(), intent, resolvedType, null,
                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
                getUserId());
    } catch (RemoteException e) {
        ...
    }
}

ActivityManagerService#broadcastIntent

public final int broadcastIntent(...) {
        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();
            //调用 broadcastIntentLocked
            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;
        }
    }
}

private final int broadcastIntentLocked(...) {
    ...
    if ((receivers != null && receivers.size() > 0)
        || resultTo != null) {
    //根据intent的flag来判断前台队列或者后台队列
    BroadcastQueue queue = broadcastQueueForIntent(intent);
    //创建BroadcastRecord
    BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
            callerPackage, callingPid, callingUid, resolvedType,
            requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
            resultData, resultExtras, ordered, sticky, false, userId);

    boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
    if (!replaced) {
        //将BroadcastRecord加入到有序广播队列
        queue.enqueueOrderedBroadcastLocked(r);
        //处理广播
        queue.scheduleBroadcastsLocked();
    }
}
    return ActivityManager.BROADCAST_SUCCESS;
}

把静态注册和动态注册的广播,按照优先级不同存储在不同的列表中,然后把列表合并到recevers 列表中。最后调用 BroadcastQueuescheduleBroadcastsLocked。

2.3 广播的处理

BroadcastQueue#scheduleBroadcastsLocked()

 public void scheduleBroadcastsLocked() {
        //Handler 发送消息 BroadcastHandler 
        mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
        mBroadcastsScheduled = true;
    }

BroadcastHandler

private final class BroadcastHandler extends Handler {

    public void handleMessage(Message msg) {
        switch (msg.what) {
            case BROADCAST_INTENT_MSG: {
                //进行消息处理
                processNextBroadcast(true); 
            } break;
            ...
    }
}

BroadcastQueue#processNextBroadcast()

final void processNextBroadcast(boolean fromMsg) {
    synchronized(mService) {
        //处理无序广播
        while (mParallelBroadcasts.size() > 0) {
            r = mParallelBroadcasts.remove(0);
            r.dispatchTime = SystemClock.uptimeMillis();
            r.dispatchClockTime = System.currentTimeMillis();
            final int N = r.receivers.size();
            for (int i=0; i<N; i++) {
                Object target = r.receivers.get(i);
                //分发广播给已注册的receiver 
                deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
            }
            //将广播添加历史统计
            addBroadcastToHistoryLocked(r);
        }
        ...
    }    

BroadcastQueue#deliverToRegisteredReceiverLocked()

private void deliverToRegisteredReceiverLocked(BroadcastRecord r, BroadcastFilter filter, boolean ordered) {
    ...
    //检查广播的权限
    ...
        //performReceiveLocked 处理广播
        performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
                new Intent(r.intent), r.resultCode, r.resultData,
                r.resultExtras, r.ordered, r.initialSticky, r.userId);
        if (ordered) {
            r.state = BroadcastRecord.CALL_DONE_RECEIVE;
        }
        ...
    }
}

BroadcastQueue#performReceiveLocked()

private static void performReceiveLocked(...) throws RemoteException {
    //通过binder,向 receiver 发送intent
    if (app != null) {
        if (app.thread != null) {
            //代码一:调用 ApplicationThreadProxy 类对应的方法 
            app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
                    data, extras, ordered, sticky, sendingUser, app.repProcState);
        } else {
           ...
        }
    } else {
        //调用者进程为空,则执行该分支
        receiver.performReceive(intent, resultCode, data, extras, ordered,
                sticky, sendingUser);
    }
}

代码一:ActivityThread#scheduleRegisteredReceiver()

public void scheduleRegisteredReceiver(...) throws RemoteException {
            updateProcessState(processState, false);
            //IIntentReceiver 的 performReceive 方法,具体实现 LoadedApk.ReceiverDispatcher.InnerReceive
            receiver.performReceive(intent, resultCode, dataStr, extras, ordered,sticky, sendingUser);
        }

LoadedApk.ReceiverDispatcher.InnerReceive

  public void performReceive(Intent intent, int resultCode, String data,
                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
            //把广播的 intent 对象封装为 Args
            final Args args = new Args(intent, resultCode, data, extras, ordered,sticky, sendingUser);
            ...
            // H 类 post
            if (intent == null || !mActivityThread.post(args.getRunnable())) {
                ...
            }
        }

Args#getRunnable()

public final Runnable getRunnable() {
                return () -> {
                   ...
                    try {
                        ...
                        //调用了onReceive 方法
                        receiver.onReceive(mContext, intent);
                    }
}