在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的切换的东东,到底是咋回事呢

解决方案 »

  1.   

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

  2.   

    整个来说比较麻烦了
    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信息来读取适合文件夹中的资源以及布局文件。希望这是楼主想知道的
      

  3.   

    也就是说在acvititythread收到onConfigurationChanged消失的之前,所有的view已经被重绘了?我去看看viewroot的draw。。
    谢谢!
      

  4.   

    你好,能否详细点说明呢,ondraw函数里是怎么画的,看不太明白,还有wms里是怎么收到sensor时间的,好像没有看到相关的代码呢,谢谢了。。
      

  5.   


    你自己搜索一下wms和ams代码里面的orientation的处理就可以看到了
    onDraw怎么画是各个view自己实现的 wms只是去遍历整个Activity的view tree
      

  6.   

    我跟了下,发现和楼上大神说的有点差异:
    首先是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的还没搞清楚,求指教,谢谢!
      

  7.   

    在xml文件里加上 android:orientation="vertical|horizontion"
    手机要支持方向传感器,就能达到自动切换的目的。因为方向改变导致配置的改变,就会触发配置改变事件的执行。
      

  8.   

    你说的是对的
    wms有一个分支不太一样 scheduleActivityConfigurationChanged是在应用自己handle这个config change的时候调用的
    但是系统一般来说会走这个默认的流程,会首先判断应用是不是会handle
    如果不会 是先会走系统默认流程 去判断当前是resume还是pause 
    然后走不同的分支 我说的是系统默认分支 并不是应用自己handle的分支
    至于ondraw函数是系统默认流程的分支中的 
      

  9.   

    又看了下,调用的过程如下:
    WMS在setNewConfiguration中会对当前的config进行设置,并在performLayoutAndPlaceSurfacesLocked中的某一步对当前的已经freezd的window进行resize,从而调到viewroot的resize方法,对所有的view进行relayout重绘,等surface重绘完成后解锁屏幕并显示出来。
    现在疑问只有一个了,layout是如何选择的?viewroot中收到updateConfiguration的时候,只有WMS传入的config参数,而且他并没有使用传入的,而是获取当前decorview的config。
    还要再继续跟踪下,这部分代码量相当大,看的头都晕了
      

  10.   

    现在疑问只有一个了,layout是如何选择的?
    你的意思是在转屏的时候如何定位layout.xml的文件夹?
      

  11.   

    是的,其实我在修改browser的一个bug,点击首页的某个图标(会新起1个browser activity),横屏切换过来后,还是竖屏的layout,图像是被scale了,所以右边会有空白的地方。显示的流程我看了,是在activitythread收到onconfigchang事件后会->handleConfigurationChanged->applyConfigurationToResourcesLocked->Resources.updateSystemConfiguration这里会对resource进行UPdate。
    在viewroot里画的时候resource应该layout和res都准备好了才对。
    问题归结于layout没切过去,这个layout是咋定位的捏,求指教= =。
      

  12.   

    这个定位很复杂了
    基本上是属于资源访问流程里面的内容了
    主体逻辑是在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就差不多了
      

  13.   

    还是不行呢,横屏切换过来的时候,已经在activitythread里applyConfigurationToResourcesLocked中调用了res的updateConfiguration,我发现在viewroot里resize的时候,宽和高已经切对了,但是layout还是用的竖屏的layout所以还是没有找到木有切换layout的原因。。
    在res的update中会设置mAssets.setConfiguration,不知道这个会不会让layout重载?
      

  14.   

    原理已经讲明白了
    剩下debug只能靠你自己查了
    没环境 没代码 没log 三无bug怎么上csdn问啊
      

  15.   

    如果你在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希望对你有帮助