android 12 framework开发第53节-Activity的reLaunch及onConfigurationChanged android源码分析

hi,同学们大家好!

1、Configuration应用开发背景

今天要给大家分享内容就是我们应用开发时候经常会遇到问题,那就是如果系统一些属性变化了,比如语言,横竖屏幕,深色模式等。就会导致系统当前的TopActivity会进行destory后进行重新create情况。如果不想要reCreate Activity那么我们就需要到AndroidManifest中去声明对应的configChange,这个 时候就会让Activity不重新reCreate,即Activity可以不需要重建,但是Activity就会执行对应回调onConfigurationChanged。

入门课,实战课,跨进程专题,input专题

在这里插入图片描述在这里插入图片描述

2、源码分析Activity的relaunch部分

这里 我们可以先分析Activity的reLaunch部分即Activity的重建
那怎么分析呢?
这里我们就以一些log线索来入手,因为大家知道源码分析的话因为源码太多,你得找到一个合适的切入点,不然确实分析源码基本等于大海捞针。
寻找切入点:
这里我们都是知道Activity重新创建会执行onDestroy,我们就在onDestroy进行堆栈拦截看看是哪里调用过来的。
在这里插入图片描述

这里很明显我们看出来了,其实是因为应用进程执行了ActivityRelaunchItem这个跨进程通信类,导致执行了对应的handleRelaunchActivityInner,再执行到handleDestroyActivity方法

那么这里其实 我们重点就应该放到具体服务端是哪里传递了ActivityRelaunchItem。

这里通过堆栈或者 调试方法 已经不起作用了,因为 是跨进程方式,当然无法追踪。
那就只能grep方式:
结果如下
在这里插入图片描述
明显我们就知道在ActivityRecord类中
在这里插入图片描述
这里调用其实是被 ensureActivityConfiguration调用的

具体调用栈:
在这里插入图片描述
这里就有个疑问了,config变化了难道就一定要进行relaunch么?这个就是我们接下来要分析的
onConfigurationChanged情况

3、源码分析非relaunch情况,执行onConfigurationChanged情况

前面我们已经知道config变化后就2种情况
1 Activity重启
2 Activity不进行重启,但要进行AndroidManifest的声明,然后会会回调onConfigurationChanged的方法

直接重启和Manifest中声明的差异到底在哪里呢?

    boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
            boolean ignoreVisibility) {
            //省略

        if (shouldRelaunchLocked(changes, mTmpConfig) || forceNewConfig) {
          //省略
            if (mState == PAUSING) {
                deferRelaunchUntilPaused = true;
                preserveWindowOnDeferredRelaunch = preserveWindow;
                return true;
            } else {
      //省略
                relaunchActivityLocked(preserveWindow);
                }
                            // All done...  tell the caller we weren't able to keep this activity around.
            return false;
            }
  // Default case: the activity can handle this new configuration, so hand it over.
        // NOTE: We only forward the override configuration as the system level configuration
        // changes is always sent to all processes when they happen so it can just use whatever
        // system level configuration it last got.
        if (displayChanged) {
            scheduleActivityMovedToDisplay(newDisplayId, newMergedOverrideConfig);
        } else {
            scheduleConfigurationChanged(newMergedOverrideConfig);
        }

        return true;
    }

这里其实就可以看出来执行scheduleConfigurationChanged其实最后就会导致Activity的onConfigurationChanged的执行
但是前面shouldRelaunchLocked如果为true,那么就会导致Activity的重启

故问题关键变成了 shouldRelaunchLocked方法

/**
     * When assessing a configuration change, decide if the changes flags and the new configurations
     * should cause the Activity to relaunch.
     *
     * @param changes the changes due to the given configuration.
     * @param changesConfig the configuration that was used to calculate the given changes via a
     *        call to getConfigurationChanges.
     */
     //这里就判断十分会导致Activity进行重启,根据changes这个值与manifet中值比较
    private boolean shouldRelaunchLocked(int changes, Configuration changesConfig) {
    //这里 非常关键会获取和activity相关的configChange,其实也就是manifest中声明的那些
        int configChanged = info.getRealConfigChanged();
        boolean onlyVrUiModeChanged = onlyVrUiModeChanged(changes, changesConfig);
//省略

        return (changes&(~configChanged)) != 0;//这里会进行比较,如果不再manifest,则返回true
    }

那么来看看info.getRealConfigChanged();具体实现情况:

public int getRealConfigChanged() {
    return applicationInfo.targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB_MR2
            ? (configChanges | ActivityInfo.CONFIG_SCREEN_SIZE
                    | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE)
            : configChanges;
}

这里其实就是ActivityInfo类中的configChanges变量
那么configChanges变量又是哪来的呢?
在这里插入图片描述

其实在包解析时候就已经进行了获取

相关源码及资料
Log.i("qq群","422901085");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值