BroadcastReceiver

2025-06-27

Android的广播机制

Anroid提供了一种消息广播机制,用于向关心相应事件的组件发送通知,通过ActivityMangerServiceActivityService都可以将BroadcastReceiver注册到ActivityMangerService中,并监听自己想要的事件,同时提供了静态注册、动态注册和广播优先级等机制

broad_cast

注册BroadcastReceiver

sequenceDiagram
autoNumber

box Receiver Process
    participant receiver
    participant ContextWrapper
    participant ContextImpl
    participant ActivityManagerProxy
end

box System Server
    participant ActivityManagerService
end

receiver ->> ContextWrapper: registerReceiver
ContextWrapper ->> ContextImpl: registerReceiver
ContextImpl ->> ContextImpl : registerReceiverInternal
ContextImpl ->> ActivityManagerProxy: registerReceiver
ActivityManagerProxy ->> ActivityManagerService: registerReceiver

step 1 想要监听某种消息的receiver调用其父类ContextWrapperregisterReceiver方法:

public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter) {
    return mBase.registerReceiver(receiver, filter);
}

mBase是一个ContextImpl类型的对象

step 2 执行ContextImplregisterService方法:

public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
    return registerReceiver(receiver, filter, null, null);
}

public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) {
    return registerReceiverInternal(receiver, getUserId(),
            filter, broadcastPermission, scheduler, getOuterContext());
}

,调用了registerReceiverInternal方法

step 3 执行registerReceiverInternal方法:

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) {
            ...
            rd = mPackageInfo.getReceiverDispatcher(
                receiver, context, scheduler,
                mMainThread.getInstrumentation(), true);
        }else{
            ...
            rd = new LoadedApk.ReceiverDispatcher(
                receiver, context, scheduler, null, true).getIIntentReceiver();
        }
    }
    try {
        return ActivityManagerNative.getDefault().registerReceiver(
                mMainThread.getApplicationThread(), mBasePackageName,
                rd, filter, broadcastPermission, userId);
    } catch (RemoteException e) {
        return null;
    }
}

,首先执行gerReceiverDispatcher方法,将receiver包装成IIntentReceiver类型的Binder对象,然后调用ActivityManagerNative.getDefault()方法获取一个ActivityManagerProxy对象,执行其registerReceiver方法,其中getReceiverDispatcher方法如下:

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;
        if (registered) {
            map = mReceivers.get(context);
            if (map != null) {
                rd = map.get(r);
            }
        }
        if (rd == null) {
            rd = new ReceiverDispatcher(mActivityThread.getApplicationThread(), 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();
    }
}

,方法通过receivermReceiversmap中查询是否存在对应的ReceiverDispatcher,如果存在则复用,否则创建一个新的ReceiverDispatcher rd并将<receiver,rd>存入map中,然后返回相应的IIntentReceiver对象

step 4 执行ActivityManagerProxy::registerReceiver方法,向ActivityManagerService发送一条REGISTER_RECEIVER_TRANSACTION类型的指令

step 5 ActivityManagerService侧的Stub收到消息后,执行onTransact方法,并调用ActivityManagerServiceregisterReceiver方法:

public Intent registerReceiver(IApplicationThread caller,
        IIntentReceiver receiver, IntentFilter filter, String permission) {
    synchronized(this) {
        ... 
        //查询粘性广播

        Intent sticky = allSticky != null ? (Intent) allSticky.get(0) : null;
        ReceiverList rl
            = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
        if (rl == null) {
            rl = new ReceiverList(this, callerApp,
                    Binder.getCallingPid(),
                    Binder.getCallingUid(), receiver);
            if (rl.app != null) {
                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 bf = new BroadcastFilter(filter, rl, permission);
        rl.add(bf);
        ...
        mReceiverResolver.addFilter(bf);
        ...
        return sticky;
    }
}

,首先查询是否有粘性广播,然后,从mRegisteredReceivers中获取一个与receiver对应的ReceiverList r1,如果不存在则创建一个并将r1加入到r1.app.receivers中,并向mRegisteredReceivers中注册<receiver, r1>,此后,创建一个BroadcastFilter bf,并加入到r1中,并给mReceiverResovler添加一个filter bf

ActivityManagerService发送广播

sequenceDiagram
autoNumber
box sender Process
participant sender
participant ContextWrapper
participant ContextImpl
participant ActivityManagerProxy
end

sender ->> ContextWrapper: sendBroadcast
ContextWrapper->>ContextImpl: sendBroadcast
ContextImpl->>ActivityManagerProxy:sendBroadcastIntent

step 1 广播发送者调用ContextWrappersendBroadcast方法:

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

mBase指向一个ContextImpl对象,方法调用了ContextImplsendBroadcast方法

step 2 执行ContextImpl::sendBroadcast方法:

public void sendBroadcast(Intent intent) {
    String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    try {
        ActivityManagerNative.getDefault().broadcastIntent(
            mMainThread.getApplicationThread(), intent, resolvedType, null,
            Activity.RESULT_OK, null, null, null, false, false);
    } catch (RemoteException e) {
    }
}

,通过ActivityMangerNative.getDefault获取到了ActivityManagerProxy,并执行broadcastIntent方法

step 3 执行 ActivityManagerProxy::broadcastIntent方法:

public int broadcastIntent(IApplicationThread caller,
        Intent intent, String resolvedType,  IIntentReceiver resultTo,
        int resultCode, String resultData, Bundle map,
        String requiredPermission, boolean serialized,
        boolean sticky) throws RemoteException{
    ...
    mRemote.transact(BROADCAST_INTENT_TRANSACTION, data, reply, 0);
    ...
}

,向ActivityManagerService发送了一个BROADCAST_INTENT_TRANSACTION的请求

ActivityMangerService转发广播

sequenceDiagram
autoNumber
box sender process
participant ActivityManagerProxy
end
box System Server
participant ActivityManagerService
participant Handler
participant ApplicationThreadProxy
participant IIntentReceiver$Proxy
end
ActivityManagerProxy->>+ActivityManagerService: broadcastIntent
ActivityManagerService->>ActivityManagerService: broadcastIntentLocked
ActivityManagerService->>+Handler: sendEmptyMessage/handleMesage
deactivate ActivityManagerService
Handler->>+ActivityManagerService: processNextBroadcast
deactivate Handler
ActivityManagerService->>+ActivityManagerService:deliverToRegisteredReceiverLocked
ActivityManagerService->>ActivityManagerService:performReceiveLocked
alt 需要Application接收广播
ActivityManagerService->>ApplicationThreadProxy: scheduleRegisteredReceiver
else 不需要
ActivityManagerService->>-IIntentReceiver$Proxy: performReceive
end
deactivate ActivityManagerService

step 1 ActivityManagerService侧的Stub接受到请求后,执行onTransact方法,并调用ActivityManagerService::broadcastIntent方法,执行broadcastIntent方法:

public final int broadcastIntent(IApplicationThread caller,
        Intent intent, String resolvedType, IIntentReceiver resultTo,
        int resultCode, String resultData, Bundle map,
        String requiredPermission, boolean serialized, boolean sticky) {
    synchronized(this) {
        ...
        int res = broadcastIntentLocked(callerApp,
                callerApp != null ? callerApp.info.packageName : null,
                intent, resolvedType, resultTo,
                resultCode, resultData, map, requiredPermission, serialized,
                sticky, callingPid, callingUid);
        ...
        return res;
    }
}

,调用了自己的broadcastIntentLocked方法

step 2 执行broadcastIntentLocked方法:

private final int broadcastIntentLocked(ProcessRecord callerApp,
        String callerPackage, Intent intent, String resolvedType,
        IIntentReceiver resultTo, int resultCode, String resultData,
        Bundle map, String requiredPermission,
        boolean ordered, boolean sticky, int callingPid, int callingUid) {
    intent = new Intent(intent);
    ...

    //找到要接受广播的receivers
    List receivers = null;
    List<BroadcastFilter> registeredReceivers = null;
    try {
        if (intent.getComponent() != null) {
            ActivityInfo ai = AppGlobals.getPackageManager().
                getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
            if (ai != null) {
                receivers = new ArrayList();
                ResolveInfo ri = new ResolveInfo();
                ri.activityInfo = ai;
                receivers.add(ri);
            }
        } else {
            if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
                         == 0) {
                    receivers =
                        AppGlobals.getPackageManager().queryIntentReceivers(
                                intent, resolvedType, STOCK_PM_FLAGS);
            }
            registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
        }
    } 
    ...
    int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
    //如果是无序广播,则优先发送给动态注册的接收者
    if (!ordered && NR > 0) {
        BroadcastRecord r = new BroadcastRecord(intent, callerApp,
                callerPackage, callingPid, callingUid, requiredPermission,
                registeredReceivers, resultTo, resultCode, resultData, map,
                ordered, sticky, false);
        //找到pending的消息并根据`replacePending`标志位判断是否需要替换
        ...
        if (!replaced) {
            mParallelBroadcasts.add(r);
            scheduleBroadcastsLocked();
        }
        registeredReceivers = null;
        NR = 0;
    }
    int ir = 0;
    ...
    //合并动态注册与静态注册的receiver
    while (ir < NR) {
        if (receivers == null) {
            receivers = new ArrayList();
        }
        receivers.add(registeredReceivers.get(ir));
        ir++;
    }
    //发送广播
    if ((receivers != null && receivers.size() > 0)
            || resultTo != null) {
        BroadcastRecord r = new BroadcastRecord(intent, callerApp,
                callerPackage, callingPid, callingUid, requiredPermission,
                receivers, resultTo, resultCode, resultData, map, ordered,
                sticky, false);
        ...
        boolean replaced = false;
        //找到pending的消息并根据`replacePending`标志位判断是否需要替换
        ...
        if (!replaced) {
            mOrderedBroadcasts.add(r);
            scheduleBroadcastsLocked();
        }
    }
    return BROADCAST_SUCCESS;
}

,首先,方法找到需要接受广播的所有receiver,分为以下类型:

  1. intent为显式Intent时,会通过AppGlobals.getPackageManager().getReceiverInfo方法获取到对应的组件
  2. 如果FLAG_RECEIVER_REGISTERED_ONLY标志位为假,表明广播可以发送给静态注册的receiver,通过AppGlobals.getPackageManager().queryIntentReceivers方法找到目标receivers
  3. 通过registeredReceivers记录所有动态注册的receiver

, 当找到receiver后,发送广播分为两种类型:

  1. 当广播不是顺序的时,如果存在动态注册的receiver,则优先将消息发送给动态注册的receiver
  2. 然后,合并receiversregisteredReceivers,并发送广播

在两种发送广播的类型中,都首先会为要发送的广播创建一个BroadcastRecord,然后判断是否需要替代pending的广播,最后将record加入到mParallelBroadcastsmOrderedBroadcasts中,并调用scheduleBroadcastLocked方法

step 3 执行scheduleBroadcastLocked方法:

private final void scheduleBroadcastsLocked() {
    ...
    if (mBroadcastsScheduled) {
        return;
    }
    mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
    mBroadcastsScheduled = true;
}

mBroadcastsScheduled表示是否消息已经被处理了,mHandler指向了ActivityManagerService中重写的一个Handler类型对象,并向其发送一个BROADCAST_INTENT_MSG类型的消息,mHandler执行Handler::handleMessage方法:

case BROADCAST_INTENT_MSG: {
    if (DEBUG_BROADCAST) Slog.v(
            TAG, "Received BROADCAST_INTENT_MSG");
    processNextBroadcast(true);
} break;

,调用了ActivityManagerServiceprocessNextBroadcast方法

step 4 执行processNextBroadcast方法:

private final void processNextBroadcast(boolean fromMsg) {
    synchronized(this) {
        BroadcastRecord r;
        ...
        if (fromMsg) {
            mBroadcastsScheduled = false;
        }
        //对于非顺序广播,直接进行发送
        while (mParallelBroadcasts.size() > 0) {
            r = mParallelBroadcasts.remove(0);
            r.dispatchTime = SystemClock.uptimeMillis();
            final int N = r.receivers.size();
            ...
            for (int i=0; i<N; i++) {
                Object target = r.receivers.get(i);
                ...
                deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
            }
            addBroadcastToHistoryLocked(r);
            ...
        }
        //对于顺序广播,找到下一个需要发送的广播
        ...
        boolean looped = false;    
        do {
            ...
            r = mOrderedBroadcasts.get(0);
            boolean forceReceive = false;
            int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
            ...
            if (r.receivers == null || r.nextReceiver >= numReceivers
                    || r.resultAbort || forceReceive) {
                ...
                cancelBroadcastTimeoutLocked();
                ...
                addBroadcastToHistoryLocked(r);
                mOrderedBroadcasts.remove(0);
                r = null;
                looped = true;
                continue;
            }
        } while (r == null);

        int recIdx = r.nextReceiver++;
        r.receiverTime = SystemClock.uptimeMillis();
        ...
        Object nextReceiver = r.receivers.get(recIdx);

        //如果接收者是动态注册的,直接发送消息
        if (nextReceiver instanceof BroadcastFilter) {
            BroadcastFilter filter = (BroadcastFilter)nextReceiver;
            ...
            deliverToRegisteredReceiverLocked(r, filter, r.ordered);
            if (r.receiver == null || !r.ordered) {
                ...
                //说明当前接收者处理完了广播,再次调用scheduleBroadcastLocked方法继续处理广播
                r.state = BroadcastRecord.IDLE;
                scheduleBroadcastsLocked();
            }
            return;
        }


        //如果接收者是静态注册的,那么有可能还没有启动
        ResolveInfo info =
            (ResolveInfo)nextReceiver;
        ...
        String targetProcess = info.activityInfo.processName;
        r.curComponent = new ComponentName(
                info.activityInfo.applicationInfo.packageName,
                info.activityInfo.name);
        r.curReceiver = info.activityInfo;
        ProcessRecord app = getProcessRecordLocked(targetProcess,
                info.activityInfo.applicationInfo.uid);
        if (app != null && app.thread != null) {
            try {
                processCurBroadcastLocked(r, app);
                return;
            } 
            ...
        }
        if ((r.curApp=startProcessLocked(targetProcess,
                info.activityInfo.applicationInfo, true,
                r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
                "broadcast", r.curComponent,
                (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
                        == null) {
            ...
            scheduleBroadcastsLocked();
            r.state = BroadcastRecord.IDLE;
            return;
        }
        mPendingBroadcast = r;
        mPendingBroadcastRecvIndex = recIdx;
    }
}
  1. 对于非顺序广播,直接调用deliverToRegisteredReceiverLocked方法进行发送
  2. 对于顺序广播,在mOrderedBroadcasts找到一个没有发送完的广播
    • 如果下一个receiver是动态注册的,那么直接调用deliverToRegisteredReceiverLocked将消息发送给该receiver
    • 如果下一个receiver是静态注册的,则可能需要启动该组件所在的进程,然后调用deliverToRegisteredReceiverLocked发送消息

step 5 执行deliverToRegisteredReceiverLocked方法:

private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
        BroadcastFilter filter, boolean ordered) {
    boolean skip = false;
    ...
    //通过filter.requiredPermssion和r.requieredPermission互相判断对方是否有权限
    if (!skip) {
        ...
        try {
            ...
            performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
                new Intent(r.intent), r.resultCode,
                r.resultData, r.resultExtras, r.ordered, r.initialSticky);
            if (ordered) {
                r.state = BroadcastRecord.CALL_DONE_RECEIVE;
            }
        } 
        ...
    }
}

,调用performReceiveLocked方法

step 6 执行ActivityManagerService.performReceiveLocked方法:

static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
        Intent intent, int resultCode, String data, Bundle extras,
        boolean ordered, boolean sticky) throws RemoteException {
    if (app != null && app.thread != null) {
        app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
                data, extras, ordered, sticky);
    } else {
        receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
    }
}
  1. 当receiver需要通过其所在的进程来接收消息,则通过其ApplicationThreadProxy对象的scheduleRegisteredReceiver方法发送广播
  2. 否则通过注册的IIntentReceiverperformReceive方法发送广播

step 7 当需要通过进程接收广播时,执行scheduleRegisteredReceiver方法:

public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
        int resultCode, String dataStr, Bundle extras, boolean ordered, boolean sticky)
        throws RemoteException {
    ...
    mRemote.transact(SCHEDULE_REGISTERED_RECEIVER_TRANSACTION, data, null,
            IBinder.FLAG_ONEWAY);
    ...
}

,向ApplicationThread发送了一条SCHEDULE_REGISTERED_RECEIVER_TRANSACTION类型的请求

step 8 当不需要进程接收广播时,执行performReceive方法:

oneway interface IIntentReceiver {
    void performReceive(in Intent intent, int resultCode,
            String data, in Bundle extras, boolean ordered, boolean sticky);
}

IItentReceiver声明为oneway类型的aidl,会调用其生成的Proxytransact方法向远程的Stub发送一个广播请求

receiver接收广播

sequenceDiagram
autoNumber
box System Server
participant ApplicationThreadProxy
participant IIntentReceiver$Proxy
end
box receiver Process
participant ApplicationThread
participant InnerReceiver
participant ReceiveDispatcher
participant Args
participant BroadcastReceiver
end

alt 需要Application接收广播
ApplicationThreadProxy->>ApplicationThread: scheduleRegisteredReceiver
ApplicationThread->>IIntentReceiver$Proxy:performReceive
end
IIntentReceiver$Proxy->>InnerReceiver:performReceive
InnerReceiver->>ReceiveDispatcher: performReceive
ReceiveDispatcher->>Args: run
Args->>BroadcastReceiver:onReceive

step 1 执行scheduleRegisteredReceiver方法:

public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
        int resultCode, String dataStr, Bundle extras, boolean ordered,
        boolean sticky) throws RemoteException {
    receiver.performReceive(intent, resultCode, dataStr, extras, ordered, sticky);
}

,调用了远程对象的performReceive方法,这里调用是通过binder的oneway async队列保证顺序广播的有效性,而方法是由

step 2执行IIntentReceiver$ProxyperformReceive方法,会通过transact方法调用远程对象

step3 远程对象执行onTransact方法后,执行InnerReceiver::performReceive方法:

public void performReceive(Intent intent, int resultCode,
                String data, Bundle extras, boolean ordered, boolean sticky) {
            LoadedApk.ReceiverDispatcher rd = mDispatcher.get();
    ...
    if (rd != null) {
        rd.performReceive(intent, resultCode, data, extras,
                ordered, sticky);
    }
    ...
}

,每个InnerReceiver都对应了一个ReceiveDispatcher对象,调用ReceiveDispatcherperformReceive方法

step 4 执行ReceiveDispatcher::performReceive方法:

public void performReceive(Intent intent, int resultCode,
        String data, Bundle extras, boolean ordered, boolean sticky) {
    ...
    Args args = new Args();
    args.mCurIntent = intent;
    args.mCurCode = resultCode;
    args.mCurData = data;
    args.mCurMap = extras;
    args.mCurOrdered = ordered;
    args.mCurSticky = sticky;
    if (!mActivityThread.post(args)) {
        if (mRegistered && ordered) {
            IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                ...
                mgr.finishReceiver(mIIntentReceiver, args.mCurCode,
                        args.mCurData, args.mCurMap, false);
            } catch (RemoteException ex) {
            }
        }
    }
}

ArgsReceiveDispacther的一个内部类,实现了Runnable接口

step 5 执行Args::run方法:

public void run() {
    BroadcastReceiver receiver = mReceiver;
    ...
    
    IActivityManager mgr = ActivityManagerNative.getDefault();
    Intent intent = mCurIntent;
    mCurIntent = null;
    ...
    try {
        ClassLoader cl =  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);
    } 
    ...
    if (mRegistered && mCurOrdered) {
        try {
            ...
            mgr.finishReceiver(mIIntentReceiver,
                    receiver.getResultCode(),
                    receiver.getResultData(),
                    receiver.getResultExtras(false),
                    receiver.getAbortBroadcast());
        } catch (RemoteException ex) {
        }
    }
}

,执行BroadcastReceiveronReceive方法对广播消息进行处理

step 6 执行BroadcastReceiver::onReceive方法