Android屏幕旋转导致Activity重建的几种解决办法

    最近学习了Android开发的相关课程,也试着动手做了书上的例子和自己的项目,在《Android编程权威指南》的第三章介绍了Activity的生命周期,提到了旋转设备会导致Activity重建的问题以及对应的解决办法。

    教材中提到的解决方法是分别创建水平和垂直布局,再通过覆盖onSaveInstanceState(Bundle)方法保存数据,在屏幕旋转后将数据传递给新的Activity。简单来说就是保存-恢复现场。

        

    那么除了这种保存-恢复现场的方法,是否还有其他方法解决这个问题呢?答案是肯定的。我在网上搜集资料找到了以下几种方法:

方法1:禁止旋转屏幕

<activity 
  android:name=".MyActivity" 
  android:screenOrientation="portrait" 
  android:label="@string/app_name"/> 

    这个方法直接回避了问题,也影响用户体验,知道就行了……

方法2:手动处理旋转

    一般情况下Configuration的改变会导致Activity被销毁重建,但也有办法让指定的Configuration改变时不重建Activity,方法是在AndroidManifest.xml里通过android:configChanges属性指定需要忽略的Configuration名字,例如下面这样: 

<activity 
  android:name=".MyActivity" 
  android:configChanges="orientation|keyboardHidden" 
  android:label="@string/app_name"/> 

    这样设置以后,当屏幕旋转时Activity对象不会被销毁——作为替代,Activity的onConfigurationChanged()方法被触发,在这里开发者可以获取到当前的屏幕方向以便做必要的更新。既然这种情况下的Activity不会被销毁,旋转后Activity里正显示的信息(例如文本框中的文字)也就不会丢失了。 
    假如你的应用里,横屏和竖屏使用同一个layout资源文件,onConfigurationChanged()里甚至可以什么都不做。但如果横屏与竖屏使用不同的layout资源文件,例如横屏用res/layout-land/main.xml,竖屏用res/layout-port/main.xml,则必须在onConfigurationChanged()里重新调用setContentView()方法以便新的layout能够生效,这时虽然Activity对象没有销毁,但界面上的各种控件都被销毁重建了,你需要写额外的代码来恢复界面信息。 

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

  // Checks the orientation of the screen 
  if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { 
    Toast.makeText(this, "横屏模式", Toast.LENGTH_SHORT).show(); 
  } 
  else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ 
    Toast.makeText(this, "竖屏模式", Toast.LENGTH_SHORT).show(); 
  } 
} 

(注:官方不推荐使用这种方法。)

方法3:另一种保存-恢复现场的方法

    实现onRetainNonConfigurationInstance()方法保存数据,使用方法和前面的onSaveInstanceState(Bundle)差不多。

/*保存*/

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

/*重建*/

@Override 
public void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.main); 
  final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance(); 
  if (data == null) {//表示不是由于Configuration改变触发的onCreate() 
    data = loadMyData(); 
  } 
  //... 
} 

    activity的销毁和重建有时候不一定是由屏幕旋转引起的,所以还是建议使用保存-恢复现场的方法。

 

参考:https://www.cnblogs.com/laishenghao/p/5128898.html

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值