BroadcastReceiver工作流程

QuibblerQuibbler 2020-04-20 约 9 分钟 2006 次阅读

BroadcastReceiver工作流程

广播是安卓开发四大组件之一,比较常用。使用起来也很方便,具体使用参考《BroadcastReceiver:广播》。这里顺着源码看看BroadcastReceiver的实现逻辑。

1、注册/反注册


代码中注册广播只需一行代码即可注册广播:

registerReceiver(mBroadcastReceiver, intentFilter);

Context中的抽象方法

public abstract Intent registerReceiver(BroadcastReceiver receiver,IntentFilter filter);

ContextWrapper是Context的实现类,内有mBase成员变量

Context mBase;

ContextImpl

registerReceiver(BroadcastReceiver receiver, IntentFilter filter)
    registerReceiver(BroadcastReceiver receiver, IntentFilter filter,String broadcastPermission, Handler scheduler)

都是调用的registerReceiverInternal方法

ActivityManager已经非常熟悉了,但凡和四大组件相关的都会经过这里。内部封装了单例模式获取 IActivityManager对象。

public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

ActivityManagerService实现了IActivityManager,内有成员变量mRegisteredReceivers :

/**
     * Keeps track of all IIntentReceivers that have been registered for broadcasts.
     * Hash keys are the receiver IBinder, hash value is a ReceiverList.
     */
    final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();

其中的registerReceiver方法完成最终BroadcastReceiver的注册和反注册:

2、发送接收广播

这里简单梳理一下广播的发送流程,最终是在LoadedApk中调用BroadcastReceiver的onReceive()方法进行广播的接受处理。


ContextImpl

@Override
    public void sendBroadcast(Intent intent) {
        warnIfCallingFromSystemProcess();
        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
        try {
            intent.prepareToLeaveProcess(this);
            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();
        }
    }

ActivityManagerService:调用链:broadcastIntent->broadcastIntentLocked->broadcastIntentLocked

BroadcastQueue scheduleBroadcastsLocked()

mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
    mBroadcastsScheduled = true;

内部类BroadcastHandler mHandler  调用链:processNextBroadcast->processNextBroadcastLocked->deliverToRegisteredReceiverLocked->performReceiveLocked

app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
                            data, extras, ordered, sticky, sendingUser, app.getReportedProcState());


app是ProcessRecord类型参数

IApplicationThread thread

IApplicationThread实现类ApplicationThread是ActivityThread的内部类

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);
        }

这里又用到了IIntentReceiver.aidl,它的实现类是LoadedApk内部类 ReceiverDispatcher : static  InnerReceiver extends IIntentReceiver.Stub

ReceiverDispatcher

performReceive(Intent intent, int resultCode, String data,
                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
       ...
       mActivityThread.post(args.getRunnable());
   }

Args是 LoadedApk的内部类,继承了BroadcastReceiver.PendingResult类,getRunnable()方法返回一个Runnable 对象,执行:

receiver.onReceive(mContext, intent);

完成BroadcastReceiver的onReceive()方法对广播接收处理。

更多资料:

        android Application Component研究之BroadcastReceiver

相关推荐