Android 动态广播注册流程(广播1)

1. 动态广播注册的流程

先看一下大致文件和流程如下(activity中动态注册广播):
在这里插入图片描述

2. 新建一个动态广播接收者

广播好久之前就准备写了,最近有时间就先把广播这部分写完

这篇文章就先将动态广播注册的流程

先看一下,在一个activity中注册一个亮屏的动态广播

    //新建一个BroadcastReceiver,用于接收广播
    public BroadcastReceiver mDynamicReceiver = new BroadcastReceiver() {
   
   
        @Override
        public void onReceive(Context context, Intent intent) {
   
   
            //onReceive是广播处理的时候的接收方法
            Log.e("yunhen", "MyReceiver dynamic intent = " + intent.getAction());
        }
    };

	//在需要注册广播的时候调用,写下类似下面的代码
	//新建一个IntentFilter,意图过滤器
	IntentFilter filter = new IntentFilter();
	//增加亮屏的行为action
	filter.addAction(Intent.ACTION_SCREEN_ON);
	//注册广播,广播接受者是mDynamicReceiver,意图过滤器是filter
	mContext.registerReceiver(mDynamicReceiver, filter);

3. App部分的registerReceiver

  1. activity中的registerReceiver,其调用的是ContextWrapper的registerReceiver
//ContextWrapper.java
    public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter) {
   
   
        return mBase.registerReceiver(receiver, filter);
    }

1.1) 至于mBase就是ContextImpl,这个又是在哪里设置的呢?
一个是在构造函数里面设置,一个是调用attachBaseContext设置,
如果是activity的mBase则是调用attachBaseContext设置

//ContextWrapper.java
    public ContextWrapper(Context base) {
   
   
        mBase = base;
    }
    protected void attachBaseContext(Context base) {
   
   
        if (mBase != null) {
   
   
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }

1.2) 在ActivityThread.java的performLaunchActivity(启动应用时发出的LaunchActivityItem会执行activity生命周期的内容)
会新建new ContextImpl,并进行mBase赋值
//新建new ContextImpl流程
ActivityThread.java: performLaunchActivity->createBaseContextForActivity
ContextImpl.java: ->createActivityContext->new ContextImpl

得到ContextImpl之后通过activity.attach进行mBase下一步赋值

//ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
   
   
//...
//创建ContextImpl
ContextImpl appContext = createBaseContextForActivity(r);
//...
//将ContextImpl的mOuterContext设置成activity
appContext.setOuterContext(activity);
//将appContext赋值给Activity(Activity是ContextWrapper的子类)的mBase对象,
//在这里上面2个(mBase/mOuterContext)是一样的
activity.attach(appContext, this, getInstrumentation(), r.token,
        r.ident, app, r.intent, r.activityInfo, title, r.parent,
        r.embeddedID, r.lastNonConfigurationInstances, config,
        r.referrer, r.voiceInteractor, window, r.configCallback,
        r.assistToken, r.shareableActivityToken);
//...
}

private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
   
   
    final int displayId = ActivityClient.getInstance().getDisplayId(r.token);
    //此处在ActivityThread将this传入ContextImpl的mMainThread
    ContextImpl appContext = ContextImpl.createActivityContext(
            this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
    //...
    return appContext;
}

//ContextImpl.java
static ContextImpl createActivityContext(ActivityThread mainThread,
        LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId,
        Configuration overrideConfiguration) {
   
   
    if (packageInfo == null) throw new IllegalArgumentException("packageInfo");

    String[] splitDirs = packageInfo.getSplitResDirs();
    //这里是LoadedApk的getClassLoader
    ClassLoader classLoader = packageInfo.getClassLoader();

    if (packageInfo.getApplicationInfo().requestsIsolatedSplitLoading()) {
   
   
        Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "SplitDependencies");
        try {
   
   
            classLoader = packageInfo.getSplitClassLoader(activityInfo.splitName);
            splitDirs = packageInfo.getSplitPaths(activityInfo.splitName);
        } catch (NameNotFoundException e) {
   
   
            // Nothing above us can handle a NameNotFoundException, better crash.
            throw new RuntimeException(e);
        } finally {
   
   
            Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
        }
    }

    final String attributionTag;
    if (activityInfo.attributionTags != null && activityInfo.attributionTags.length > 0) {
   
   
        attributionTag = activityInfo.attributionTags[0];
    } else {
   
   
        attributionTag = null;
    }

    //新建new ContextImpl,注意传入参数mainThread、classLoader等,还有createActivityContext函数的一些resources初始化
	//传入的UserHandle user是null
    ContextImpl context = new ContextImpl(null, mainThread, packageInfo, ContextParams.EMPTY,
            attributionTag, null, activityInfo.splitName, activityToken, null, 0, classLoader,
            null);
    context.mContextType = CONTEXT_TYPE_ACTIVITY;
    context.mIsConfigurationBasedContext = true;

    // Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY.
    displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY;

    final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
            ? packageInfo.getCompatibilityInfo()
            : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;

    final ResourcesManager resourcesManager = ResourcesManager.getInstance();

    // Create the base resources for which all configuration contexts for this Activity
    // will be rebased upon.
    context.setResources(resourcesManager.createBaseTokenResources(activityToken,
            packageInfo.getResDir(),
            splitDirs,
            packageInfo.getOverlayDirs(),
            packageInfo.getOverlayPaths(),
            packageInfo.getApplicationInfo().sharedLibraryFiles,
            displayId,
            overrideConfiguration,
            compatInfo,
            classLoader,
            packageInfo.getApplication() == null ? null
                    : packageInfo.
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值