BroadcastReceiver工作流程

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

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

相关推荐

精选
ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager
Android

ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager

ViewPager1、ViewPagerandroidx.viewpager.widget.ViewPager,Android中使用非常广泛的控件,可以说是APP必备:首次打开引导页、页面Banner广告等。常用方法:setAdapter() 设置适配器setOffscreenPageLimit() 设置缓存的页面个数,默认是 1setCurrentItem() 跳转到特定的页面setOnPage

1.1k
获取Android内置WebView内核版本
Android

获取Android内置WebView内核版本

获取Android内置WebView内核版本竟然能遇到这样奇葩的事情,网页用的技术过于新颖,以至于只支持高版本Chromium内核的,低版本安卓系统中内置的内核版本较低,无法加载前端页面。1、设置查看在系统设置里 > 应用 > 应用管理 > 显示系统应用,查看WebView组件:2、页面查看通过WebView发起的网络请求,都会带上浏览器的UA,通常页面都可以通过UA判断浏览器的内核版本。这里有两

1.1w
Android 14适配总结
Android

Android 14适配总结

Android 14适配总结毕业工作至今已经适配了三个Android大版本,从Android 11到Android 12、再到Android 13。2023年,Google即将推出的Android 14,上半年已经开始第一批适配。现在,第四个Android版本已经适配完,总结记录一下。1、Android 14计划Google一般会在2月份对外发布预告,同时放出开发者预览版。“拉通”各大平台、厂商以

1.1w