Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 393|回复: 0

Android开发 旋转屏幕导致Activity重建解决方法(转)

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-5-19 13:01:10 | 显示全部楼层 |阅读模式

     

     

       文章来源:http://www.jb51.net/article/31833.htm

     

      Android开发文档上专门有一小节解释这个问题。简单来说,Activity是负责与用户交互的最主要机制,任何“设置”(Configuration)的改变都可能对Activity的界面造成影响,这时系统会销毁并重建Activity以便反映新的Configuration。


      “屏幕方向”(orientation)是一个Configuration,通过查看Configuration类的javadoc可以看到其他Configuration还有哪些:

    如fontScale、keyboardHidden和locale等等。
      当屏幕旋转时,这个Configuration就发生了改变,因此当前显示的Activity需要被重建,Activity对象会被终止,它的onPause()、onStop()和onDestroy()方法依次触发,然后一个新的Activity对象被创建,onCreate()方法被触发。假设屏幕旋转前,用户正在手机上填写一个注册表单,如果处理不当,用户会发现旋转后的表单变成空白的了,严重影响使用体验。


    要解决这个问题有三种方法:


    方法1:禁止旋转屏幕
    毫无疑问,这是最懒的办法了,相当于回避了本文提出的问题,方法如下看看就好: 

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


    方法2:旋转后恢复现场
      既然Activity会被销毁,那么我们就可以使用前文介绍过的“持久化/恢复现场”方法来解决。即在onPause()里将用户当前已经输入的内容保存到数据库或Preference,在onCreate()方法里读取并填充到表单中,这也是官方推荐的方法。
    需要补充一点,如果Activity重建需要耗费大量资源或需要访问网络导致时间很长,可以实现onRetainNonConfigurationInstance()方法将所需数据先保存到一个对象里,像下面这样: 

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

      重建时,在onCreate()方法里通过getLastNonConfigurationInstance()方法获得之前保存的数据,如下所示:

    @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(); 
      } 
      //... 
    } 

     

    方法3:手工处理旋转
      一般情况下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();   } }

      官方的Android开发文档不建议使用这种方式处理Configuration改变:
      Note: Using this attribute should be avoided and used only as a last-resort. Please read Handling Runtime Changes for more information about how to properly handle a restart due to a configuration change.

     

    最佳实践: 
      考虑到旋转屏幕并不是使Activity被销毁重建的唯一因素,仍然推荐前文介绍过的方法:在onPause()里持久化Activity状态,在onCreate()里恢复现场,可以做到一举多得;虽然Google不推荐设置android:configChanges属性的方式,但如果你的Activity横向纵向共用同一个layout文件,方法3无疑是最省事的。

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-19 10:39 , Processed in 0.066630 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表