求助!!横竖屏切换时layout自动切换的问题

有梦想的胖子 2012-03-26 07:41:43
在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的切换的东东,到底是咋回事呢。。。


...全文
613 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
scwhy 2012-04-01
  • 打赏
  • 举报
回复
如果你在AndroidManifest.xml activty节点中配置了android:configChanges="orientation|keyboardHidden",那么activity会直接执行onConfigurationChanged()方法,如果没在配置android:configChanges则activity会执行onRestart()方法,对应用会执行生命周期的onStart()----onResume()....方法,(我觉得横竖屏应该是系统在onStart()方法中判断的吧..不是很清楚这块)

http://developer.android.com/guide/topics/resources/runtime-changes.html

希望对你有帮助
有梦想的胖子 2012-03-31
  • 打赏
  • 举报
回复
还是不行呢,横屏切换过来的时候,已经在activitythread里applyConfigurationToResourcesLocked中调用了res的updateConfiguration,我发现在viewroot里resize的时候,宽和高已经切对了,但是layout还是用的竖屏的layout。。。所以还是没有找到木有切换layout的原因。。
在res的update中会设置mAssets.setConfiguration,不知道这个会不会让layout重载?
妖怪 2012-03-31
  • 打赏
  • 举报
回复
原理已经讲明白了
剩下debug只能靠你自己查了
没环境 没代码 没log 三无bug怎么上csdn问啊
有梦想的胖子 2012-03-30
  • 打赏
  • 举报
回复
谢谢大神! 我去看看。。。
妖怪 2012-03-30
  • 打赏
  • 举报
回复
可以结贴了吧
妖怪 2012-03-30
  • 打赏
  • 举报
回复
这个定位很复杂了
基本上是属于资源访问流程里面的内容了
主体逻辑是在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就差不多了
有梦想的胖子 2012-03-30
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]

现在疑问只有一个了,layout是如何选择的?
你的意思是在转屏的时候如何定位layout.xml的文件夹?
[/Quote]
是的,其实我在修改browser的一个bug,点击首页的某个图标(会新起1个browser activity),横屏切换过来后,还是竖屏的layout,图像是被scale了,所以右边会有空白的地方。

显示的流程我看了,是在activitythread收到onconfigchang事件后会->handleConfigurationChanged->applyConfigurationToResourcesLocked->Resources.updateSystemConfiguration这里会对resource进行UPdate。
在viewroot里画的时候resource应该layout和res都准备好了才对。
问题归结于layout没切过去,这个layout是咋定位的捏,求指教= =。。。。
妖怪 2012-03-30
  • 打赏
  • 举报
回复
现在疑问只有一个了,layout是如何选择的?
你的意思是在转屏的时候如何定位layout.xml的文件夹?
有梦想的胖子 2012-03-29
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]

引用 9 楼 的回复:

我跟了下,发现和楼上大神说的有点差异:
首先是phonewindowmananger里会注册windoworientationlistener,当sensor有事件上报后,会调用onOrientationChanged,继续调用WMS里的接口setRotation。
在setRotation里会对config进行判断,如果发生了变化就会通知AMS,sendNe……
[/Quote]
又看了下,调用的过程如下:
WMS在setNewConfiguration中会对当前的config进行设置,并在performLayoutAndPlaceSurfacesLocked中的某一步对当前的已经freezd的window进行resize,从而调到viewroot的resize方法,对所有的view进行relayout重绘,等surface重绘完成后解锁屏幕并显示出来。
现在疑问只有一个了,layout是如何选择的?viewroot中收到updateConfiguration的时候,只有WMS传入的config参数,而且他并没有使用传入的,而是获取当前decorview的config。
还要再继续跟踪下,这部分代码量相当大,看的头都晕了
有梦想的胖子 2012-03-28
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

在xml文件里加上 android:orientation="vertical|horizontion"
手机要支持方向传感器,就能达到自动切换的目的。因为方向改变导致配置的改变,就会触发配置改变事件的执行。
[/Quote]
= = 我想知道的是原理。。。。
计算机刘老师 2012-03-28
  • 打赏
  • 举报
回复
在xml文件里加上 android:orientation="vertical|horizontion"
手机要支持方向传感器,就能达到自动切换的目的。因为方向改变导致配置的改变,就会触发配置改变事件的执行。
有梦想的胖子 2012-03-28
  • 打赏
  • 举报
回复
我跟了下,发现和楼上大神说的有点差异:
首先是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的还没搞清楚,求指教,谢谢!
妖怪 2012-03-28
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

引用 5 楼 dxjwolf 的回复:

整个来说比较麻烦了
sensor流程如下
sensor hardware -> G sensor kernel + driver -> sensormanager jni -> sensormanager sensorservice java -> app
在第三级 sensor会通知wms 然后wms会去查看activity stack, 然……
[/Quote]

你自己搜索一下wms和ams代码里面的orientation的处理就可以看到了
onDraw怎么画是各个view自己实现的 wms只是去遍历整个Activity的view tree
妖怪 2012-03-28
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

我跟了下,发现和楼上大神说的有点差异:
首先是phonewindowmananger里会注册windoworientationlistener,当sensor有事件上报后,会调用onOrientationChanged,继续调用WMS里的接口setRotation。
在setRotation里会对config进行判断,如果发生了变化就会通知AMS,sendNewConfiguration。
……
[/Quote]
你说的是对的
wms有一个分支不太一样 scheduleActivityConfigurationChanged是在应用自己handle这个config change的时候调用的
但是系统一般来说会走这个默认的流程,会首先判断应用是不是会handle
如果不会 是先会走系统默认流程 去判断当前是resume还是pause
然后走不同的分支 我说的是系统默认分支 并不是应用自己handle的分支
至于ondraw函数是系统默认流程的分支中的
mikebai 2012-03-27
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 horsttnann 的回复:]

系统自动识别横竖屏。在res目录下建立layout-land(横屏)和layout-port(竖屏)两个目录,相应的layout文件放在对应的文件夹内。当屏幕方向改变的时候,系统会自动从对应的文件夹内加载布局文件。
[/Quote]

所答非所问。。。。。。。。。。
LZ问得机制原理
horsttnann 2012-03-27
  • 打赏
  • 举报
回复
系统自动识别横竖屏。在res目录下建立layout-land(横屏)和layout-port(竖屏)两个目录,相应的layout文件放在对应的文件夹内。当屏幕方向改变的时候,系统会自动从对应的文件夹内加载布局文件。
有梦想的胖子 2012-03-27
  • 打赏
  • 举报
回复
召唤大神,顶。。。。。
有梦想的胖子 2012-03-27
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 dxjwolf 的回复:]

整个来说比较麻烦了
sensor流程如下
sensor hardware -> G sensor kernel + driver -> sensormanager jni -> sensormanager sensorservice java -> app
在第三级 sensor会通知wms 然后wms会去查看activity stack, 然后从整个activity栈中从后往前去走每个……
[/Quote]
你好,能否详细点说明呢,ondraw函数里是怎么画的,看不太明白,还有wms里是怎么收到sensor时间的,好像没有看到相关的代码呢,谢谢了。。
有梦想的胖子 2012-03-27
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 dxjwolf 的回复:]

整个来说比较麻烦了
sensor流程如下
sensor hardware -> G sensor kernel + driver -> sensormanager jni -> sensormanager sensorservice java -> app
在第三级 sensor会通知wms 然后wms会去查看activity stack, 然后从整个activity栈中从后往前去走每个……
[/Quote]
也就是说在acvititythread收到onConfigurationChanged消失的之前,所有的view已经被重绘了?我去看看viewroot的draw。。
谢谢!
妖怪 2012-03-27
  • 打赏
  • 举报
回复
整个来说比较麻烦了
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信息来读取适合文件夹中的资源以及布局文件。

希望这是楼主想知道的

80,493

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧