在XML里写了activity的属性为 android:configChanges="orientation|keyboardHidden"
代码里重写了onConfigurationChanged(),也有两套layout
可以正常切换横竖屏,请问系统是怎么切换横竖屏的layout的?半天也没搞清楚,不要说系统自动调用的,答得好可以加分,谢谢了!!PS:
目前我看到的流程(猜测)
activitythread.java handleActivityConfigurationChanged
applyConfigurationToResourcesLocked
Resources.java updateConfiguration
assetmanager.java setConfiguration
assetmanager.cpp AssetManager::setConfiguration
AssetManager::setLocaleLocked
AssetManager::updateResourceParamsLocked看到这里也没有关于layout的切换的东东,到底是咋回事呢
代码里重写了onConfigurationChanged(),也有两套layout
可以正常切换横竖屏,请问系统是怎么切换横竖屏的layout的?半天也没搞清楚,不要说系统自动调用的,答得好可以加分,谢谢了!!PS:
目前我看到的流程(猜测)
activitythread.java handleActivityConfigurationChanged
applyConfigurationToResourcesLocked
Resources.java updateConfiguration
assetmanager.java setConfiguration
assetmanager.cpp AssetManager::setConfiguration
AssetManager::setLocaleLocked
AssetManager::updateResourceParamsLocked看到这里也没有关于layout的切换的东东,到底是咋回事呢
sensor流程如下
sensor hardware -> G sensor kernel + driver -> sensormanager jni -> sensormanager sensorservice java -> app
在第三级 sensor会通知wms 然后wms会去查看activity stack, 然后从整个activity栈中从后往前去走每个activity的viewroot 发送消息 走viewgroup去调用view的ondraw去重绘
这个时候就涉及到ondraw时去重新载入layout布局以及横屏资源了
因为获取资源和layout的时候会在resources层读取systemPreperties的屏幕横竖屏属性
这个时候会根据当前的sensor报上的orientation信息来读取适合文件夹中的资源以及布局文件。希望这是楼主想知道的
谢谢!
你自己搜索一下wms和ams代码里面的orientation的处理就可以看到了
onDraw怎么画是各个view自己实现的 wms只是去遍历整个Activity的view tree
首先是phonewindowmananger里会注册windoworientationlistener,当sensor有事件上报后,会调用onOrientationChanged,继续调用WMS里的接口setRotation。
在setRotation里会对config进行判断,如果发生了变化就会通知AMS,sendNewConfiguration。
AMS会调用WMS的接口computeNewConfiguration来对新的config进行判断,并在updateConfigurationLocked调用activitythread的scheduleConfigurationChanged,给APPTHREAD发CONFIGURATION_CHANGED;调用ensureActivityConfigurationLocked,紧接着在activitystack里调用app.thread.scheduleActivityConfigurationChanged来给APPTHREAD发送ACTIVITY_CONFIGURATION_CHANGED消息。
到这里,我们的activitythread就会收到并处理这2个关键的消息,遍历当前的callstack,调用各个activity的onconfigrationchange.调用流程大致就是这样了,但是ondraw的还没搞清楚,求指教,谢谢!
手机要支持方向传感器,就能达到自动切换的目的。因为方向改变导致配置的改变,就会触发配置改变事件的执行。
wms有一个分支不太一样 scheduleActivityConfigurationChanged是在应用自己handle这个config change的时候调用的
但是系统一般来说会走这个默认的流程,会首先判断应用是不是会handle
如果不会 是先会走系统默认流程 去判断当前是resume还是pause
然后走不同的分支 我说的是系统默认分支 并不是应用自己handle的分支
至于ondraw函数是系统默认流程的分支中的
WMS在setNewConfiguration中会对当前的config进行设置,并在performLayoutAndPlaceSurfacesLocked中的某一步对当前的已经freezd的window进行resize,从而调到viewroot的resize方法,对所有的view进行relayout重绘,等surface重绘完成后解锁屏幕并显示出来。
现在疑问只有一个了,layout是如何选择的?viewroot中收到updateConfiguration的时候,只有WMS传入的config参数,而且他并没有使用传入的,而是获取当前decorview的config。
还要再继续跟踪下,这部分代码量相当大,看的头都晕了
你的意思是在转屏的时候如何定位layout.xml的文件夹?
在viewroot里画的时候resource应该layout和res都准备好了才对。
问题归结于layout没切过去,这个layout是咋定位的捏,求指教= =。
基本上是属于资源访问流程里面的内容了
主体逻辑是在assetManager.cpp里面在载入资源的时候会去使用ResTable_config(这个里面包含了转屏、语言、location等各种config信息)
而在android_util_AssetManager.cpp中下面的代码是对资源访问进行定位逻辑的入口
ssize_t block = res.getResource(ident, &value, false, density, &typeSpecFlags, &config);
其中config就是就是获取config用的 而ident就是resource id
在jni层就会去对应用APK包的资源进行遍历来获取id对应的路径AssetManager.cpp中
const ResTable* AssetManager::getResTable(bool required)
你要了解具体的config变换逻辑就看这里的函数实现吧 一直到ZipIO就差不多了
在res的update中会设置mAssets.setConfiguration,不知道这个会不会让layout重载?
剩下debug只能靠你自己查了
没环境 没代码 没log 三无bug怎么上csdn问啊