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

Posted learnframework

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android 12 framework开发第53节-Activity的reLaunch及onConfigurationChanged android源码分析相关的知识,希望对你有一定的参考价值。

hi,同学们大家好!

1、Configuration应用开发背景

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

入门课,实战课,跨进程专题,input专题
ps需要学习深入framework课程和课程优惠
新课程优惠获取请加入qq群:422901085

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变量又是哪来的呢?

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

以上是关于android 12 framework开发第53节-Activity的reLaunch及onConfigurationChanged android源码分析的主要内容,如果未能解决你的问题,请参考以下文章

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

android framework项目开发案例-动态隐藏Launcher上图标2

android framework项目开发案例-动态隐藏Launcher上图标2

android framework开发之广播broadcast源码分析-千里马

android framework开发之广播broadcast源码分析-千里马

Android Framework