android: 横竖屏切换总结-布局改变和数据保存  

目录:
引言
一、布局问题
二、重新载入问题

三、Q:横竖屏生命周期的切换有可能是什么样的?



        Activity在Configuration变化(比如设备横竖屏切换)时会重启Activity,即会执行onDestory()周期函数,然后onCreate(),重新创建Activity。这是因为这样可以让Activity动态适应Configuration,比如横屏时使用横屏的layout,drawable等resources,竖屏时使用竖屏的layout,drawable等resources。
      (BTW,彻底禁止翻转,可以设置android:screenOrientation的属性为nosensor)

      重启Activity可能导致布局长宽不合适,也可能导致大量数据的重新获取,网络连接的重新建立等问题,用户体验非常差。所以应该在Activity销毁前保存当前活动的状态,在Activity再次Create的时候载入配置。

     所以,Android横竖屏切换要解决的问题就两个:布局问题;二、重新载入问题。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

一、布局问题

1.禁止切换横屏或竖屏

        可以在配置Activity的地方进行如下的配置

        android:screenOrientation="portrait"

        android:screenOrientation="landscape" 

或者 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

       setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

这样就可以保证是竖屏总是竖屏了,或者横屏总是横屏。

2.可以切换横屏或竖屏

若要软件在横竖屏之间切换,由于横竖屏的高宽会发生转换,有可能会要求不同的布局。可以通过以下方法来切换布局:

1)layout-land和layout-port

      在res目录下建立layout-land(横屏的layout)和layout-port(竖屏的layout)目录,相应的layout文件不变,比如main.xml。其他的不用管,模拟器会自动寻找。

2)onCreate()中判断横竖屏

     通过this.getResources().getConfiguration().orientation判断当前是横屏还是竖屏,然后加载相应的xml布局文件。因为当屏幕变为横屏的时候,系统会重新呼叫当前Activity的OnCreate方法,你可以把以下方法放在你的 OnCreate中来检查当前的方向,然后可以让你的SetContentView来载入不同的Layout xml. 
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { 
Log.i("info", "landscape"); 

else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { 
Log.i("info", "portrait");

}

3)横竖屏切换用onConfigurationChanged

          这种方法缺点是动态适应差。比如横竖屏切换时需要你自己写代码来使用不同的layout等resource,语言设置的动态改变等,不推荐.

首先要在配置Activity的时候进行如下的配置:

          android:configChanges="orientation|keyboardHidden"
          android:label="@string/app_name">

另外需要重写Activity的onConfigurationChanged方法。实现方式如下,不需要做太多的内容:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();

        ....

   } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();

        .....
    }
}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

二、重新载入问题

1.不需要新载入

在androidmanifest.xml中加入配置android:configChanges="orientation|keyboardHidden"
横竖屏切换时调用onConfigurationChanged(Configuration newConfig)

注意:当横屏变竖屏的时候,他会调用两次onConfigurationChanged,而竖屏转横屏时他只调用一次。

2.新载入,保存之前数据不变onSaveInstanceState()onRestoreInstanceState() 

Android横竖屏切换时会触发onSaveInstanceState,而还原时会产生onRestoreInstanceState。
注意  :
   *
我们不应该保存那些依赖Activity的数据,比如Drawable,Adapter,View或者任何与Context相关联的数据。因为上一个Activity已经没有了,如果你还要保持这些资源的引用,可能导致资源泄露。

3.新载入,保存之前数据不变onRetainNonConfigurationInstance()和getLastNonConfigurationInstance()         

     需要在重新载入过程中保存之前的操作内容或数据,则需要保存之前的数据。然后在activity的 onCreate()中取出来。当然,如此就不能设置android:configChanges()了,否则就不会调用onCreate()方法。那么 数据可以保存在哪呢?Android中四种存储方法都可以。  

     还可以用Android为我们提供了onRetainNonConfigurationInstance()方法来暂时保存数据。
     当Device configuration发生改变时,将伴随Destroying被系统调用。通过这个方法可以像onSaveInstanceState()的方法一样保留变化前的Activity State,最大的不同在于这个方法可以返回一个包含有状态信息的Object,其中甚至可以包含Activity Instance本身。新创建的Activity可以继承大量来至于Parent Activity State信息。

onRetainNonConfigurationInstance这个方法最大的好处是: 
    * 当Activity曾经通过某个资源得到一些图片或者信息,那么当再次恢复后,无需重新通过原始资源地址获取,可以快速的加载整个Activity状态信息。 
    * 当Activity包含有许多线程时,在变化后依然可以持有原有线程,无需通过重新创建进程恢复原有状态。 
    * 当Activity包含某些Connection Instance时,同样可以在整个变化过程中保持连接状态。

注意
    
     * 我们不应该保存那些依赖Activity的数据,比如Drawable,Adapter,View或者任何与Context相关联的数据。因为上一个Activity已经没有了,如果你还要保持这些资源的引用,可能导致资源泄露。    
    * onRetainNonConfigurationInstance()在onSaveInstanceState()之后被调用。 
    * 调用顺序同样介于onStop() 和 onDestroy()之间。 

使用方法如下:

@Override
public Object onRetainNonConfigurationInstance() {
    final MyDataObject data = collectMyLoadedData();
    return data;
}

        在onCreate()中调用getLastNonConfigurationInstance(),获取onRetainNonConfigurationInstance()保存的数据。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance();
    if (data == null) {
        data = loadMyData();
    }
    ...
}

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Q:横竖屏生命周期的切换有可能是什么样的?

a、不设置Activityandroid:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次。

如下:启动一个Activity,

onCreate()

onStart()

onResume()

竖屏切换到横屏:(调用一次生命周期)

onSaveInstanceState()

onPause()

onStop()

onDestroy()

onCreate()

onStart()

onRestoreInstanceState()

onResume()


横屏切换到竖屏:(调用两次生命周期)

onSaveInstanceState()

onPause()

onStop()

onDestroy()

onCreate()

onStart()

onRestoreInstanceState()

onResume()

onSaveInstanceState()

onPause()

onStop()

onDestroy()

onCreate()

onStart()

onRestoreInstanceState()

onResume()


b
、设置Activityandroid:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次。


c
、设置Activityandroid:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法。




参考:
http://developer.android.com/guide/topics/resources/runtime-changes.html
http://chengbs.iteye.com/blog/1156167
http://java-admin.iteye.com/blog/730863 2711082222推荐阅读: 横竖屏切换时候activity的生命周期?2014.05.26横竖屏切换时候activity的生命周期? android代码格式化方法和Eclipse重要2013.11.06android代码格式化方法和Eclipse重要快捷键 android Provision简介(转载)2013.08.02android Provision简介(转载) android截取开机关机事件2013.07.01android截取开机关机事件 linux : XP 虚拟机报错The virtual m2012.11.22linux : XP 虚拟机报错The virtual machine android:ScrollView嵌套ListView的问2012.06.21android:ScrollView嵌套ListView的问题 Android:自适应不同分辨率的屏幕大2012.03.15Android:自适应不同分辨率的屏幕大小、方 android:dip、dp、px、sp和屏幕密度2012.02.29android:dip、dp、px、sp和屏幕密度 android:ImageView 和ImageButton的2012.06.05android:ImageView 和ImageButton的区别 android:3种菜单2012.05.29android:3种菜单 android:TextView 多行显示滚动2012.04.28android:TextView 多行显示滚动 android:windowSoftInputMode属性使2012.04.25android:windowSoftInputMode属性使用

转载自:http://2711082222.blog.163.com/blog/static/106302249201221511171909/



更多相关文章

  1. 编写android对google地图的调用
  2. Android与JS代码交互
  3. IKNinePhotoView 是一个开源的 Android(安卓)九宫格控件,可以自适
  4. 深入理解Android系统多用户
  5. Android(安卓)Task概念以及相关
  6. 源码分析Android(安卓)AsyncTask
  7. android平台phonegap框架实现原理
  8. 【阿里云镜像】切换阿里巴巴开源镜像站镜像——Fedora镜像
  9. 【阿里云镜像】切换阿里巴巴开源镜像站镜像——Debian镜像

随机推荐

  1. 探讨阿里数加平台
  2. xp sp3升级包
  3. 大数据三种典型云服务模式
  4. 如何一举拿下大厂Offer面经(附面试题)
  5. 微软大数据领域优势分析
  6. 华纳云:香港IP地址更换需要注意的事项
  7. 大数据仓库-kudu
  8. PDO连接数据库实例
  9. es软件安装
  10. 最新个税计算、个税倒推和税后倒推公式