安卓开发技术分享:旋转屏幕导致Activity重建

Android开发文档上专门有一小节解释这个问题。简单来说,Activity是负责与用户交互的最主要机制,任何“设置”(Configuration)的改变都可能对Activity的界面造成影响,这时系统会销毁并重建Activity以便反映新的Configuration。 “屏幕方向”(orientation)是一个Configuration,通过查看Configuration类的javadoc可以看到其他Configuration还有哪些:如fontScale、keyboardHidden和locale等等。

android屏幕旋转

目录[-]

  • 方法1:禁止旋转屏幕
  • 方法2:旋转后恢复现场
  • 方法3:手工处理旋转
  • 最佳实践

当屏幕旋转时,这个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()方法将所需数据先保存到一个对象里,像下面这样:

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

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

@Overridepublic 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对象没有销毁,但界面上的各种控件都被销毁重建了,你需要写额外的代码来恢复界面信息。

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

官方的安卓开发文档不建议使用这种方式处理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无疑是最省事的。

时间: 2024-10-12 07:57:25

安卓开发技术分享:旋转屏幕导致Activity重建的相关文章

Android——旋转屏幕导致Activity重建解决方法

Android开发文档上专门有一小节解释这个问题.简单来说,Activity是负责与用户交互的最主要机制,任何“设置”(Configuration)的改变都可能对Activity的界面造成影响,这时系统会销毁并重建Activity以便反映新的Configuration. “屏幕方向”(orientation)是一个Configuration,通过查看Configuration类的javadoc可以看到其他Configuration还有哪些:如fontScale.keyboardHidden和lo

安卓开发入门笔记#1 初认Activity

一.Activity基本概念 Activity是安卓开发中的重要组件,它为用户提供了基本的屏幕交互空间.简单来说,我们直观看到的应用可操作界面,其基础就是托管的activity. 一个应用通常由多个activity组成,一个activity可以启动另外一个acitvity,新的activity称为子activity,其父activity将会自动停止,并被压入stack,当子activity返回时,再从stack中弹出父activity. 二.Activity的生命周期 安卓官方文档有句话:开发一

使用最新最酷的安卓开发技术

首先开发工具当然不能用eclipse咯,当然得用android studio.api版本当然必须是23+,以支持cardview.receiveview.百分比布局等. 另外还有引入android support v7.android support design,这样界面的效果就不会太差了,也就是metal design的风格. 然后除了界面之外,还需要访问数据库,网络请求等. 对于数据库操作,android有相应的函数可以操作sqlite,不过默认的方式要用sql语句来操作,不是很方便快捷,

Docker原理(开发技术分享转发)

Docker原理Docker是啥Docker是一个程序运行.测试.交付的开放平台,Docker被设计为能够使你快速地交付应用.在Docker中,你可以将你的程序分为不同的 基础部分,对于每一个基础部分都可以当做一个应用程序来管理.Docker能够帮助你快速地测试.快速地编码.快速地交付,并且缩短你从编码到运行应用的 周期.Docker使用轻量级的容器虚拟化平台,并且结合工作流和工具,来帮助你管理.部署你的应用程序.在其核心,Docker实现了让几乎任何程序都可以在一个安全.隔离的容器中运行.安全

[SAP ABAP开发技术总结]选择屏幕——按钮、单选复选框

目录导航 声明:原创作品,转载时请注明文章来自SAP师太博客,并以超链接形式标明文章原始出处,否则将追究法律责任!原文出自: 12.6.         按钮.单选复选框.下拉框的FunCode. 91 12.6.1.     选择屏幕中的按钮... 92 12.6.2.     选择屏幕中的单选/复选按钮:点击时显示.隐藏其他屏幕元素... 92 12.6.     按钮.单选复选框.下拉框的FunCode 如果复选框与单选按钮没有设置Function Code,则它们就会像普通的输入框一样,

[SAP ABAP开发技术总结]选择屏幕——SELECT-OPTIONS

目录导航 声明:原创作品,转载时请注明文章来自SAP师太博客,并以超链接形式标明文章原始出处,否则将追究法律责任!原文出自: 12.4.         SELECT-OPTIONS. 89 12.4.1.     输入ABAP程序默认值时,需要加上“=”. 89 12.4.2.     选择条件内表多条件组合规则... 89 12.4.3.     使用SELECT-OPTIONS替代PARAMETERS. 90 12.4.     SELECT-OPTIONS SELECT-OPTIONS

[SAP ABAP开发技术总结]DIALOG屏幕流逻辑

声明:原创作品,转载时请注明文章来自SAP师太博客,并以超链接形式标明文章原始出处,否则将追究法律责任!原文出自: 12.7.     屏幕流逻辑 PROCESS BEFORE OUTPUT.PROCESS AFTER INPUT.PROCESS ON HELP-REQUEST.PROCESS ON VALUE-REQUEST. 12.7.1.           FIELD FIELD <f>. 使用FIELD语句后,屏幕字段<f>需要在该语句处理完后才传递到ABAP程序相应的字

安卓开发_分享功能

APP必备小功能,代码很简单, 1 Intent intent=new Intent(Intent.ACTION_SEND); 2 intent.setType("text/plain"); //"image/*" 3 intent.putExtra(Intent.EXTRA_SUBJECT,"共享软件"); 4 intent.putExtra(Intent.EXTRA_TEXT, "这里是分享内容"); 5 intent.s

[SAP ABAP开发技术总结]列表屏幕

目录导航 声明:原创作品,转载时请注明文章来自SAP师太博客,并以超链接形式标明文章原始出处,否则将追究法律责任!原文出自: 13.             列表屏幕... 111 13.1.         标准LIST. 112 13.2.         自定义LIST. 112 13.3.         LIST事件... 113 13.4.         Detail Lists 创建... 113 13.5.         标准的 List Status. 113 13.6.