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源码分析-千里马