Android旋转屏幕导致Activity重建

来源:互联网 发布:sai软件上色教程 编辑:程序博客网 时间:2024/05/16 05:46

        最近做一个小应用,自然想做成兼容性高点的可是布局采用Fragment。于是在应用即将完成的时候,发现了一个问题,就是屏幕旋转问题,当设备屏幕旋转,应用的Activity就会被重建。如果这会是在输入一个表单,并且快完成了。这个么一不小心一转,发现Activity被重建,之前写的东西全部消失。这等心情,简直不知道该找谁发泄。言归正传。

        Activity是负责与用户交互的最主要机制,任何“设置”(Configuration)的改变都可能对Activity的界面造成影响,这时系统会销毁并重建Activity以便反映新的Configuration。 “屏幕方向”(orientation)是一个Configuration,通过查看Configuration类的javadoc可以看到其他Configuration还有哪些:如fontScale、keyboardHidden和locale等等。 当屏幕旋转时,这个Configuration就发生了改变,因此当前显示的Activity需要被重建,Activity对象会被终止,它的onPause()、onStop()和onDestroy()方法依次触发,然后一个新的Activity对象被创建,onCreate()方法被触发。

      于是该如何去解决这种问题呢?现在手机都比较大了,旋转屏幕常有的事。方法有几种:

方法1:禁止旋转屏幕 

<span style="font-weight: bold;"> </span><activity            android:name="com.demo.demohd.PhotoPreviewActivity"            android:label="@string/title_activity_photo_preview"            android:screenOrientation="landscape"            android:theme="@style/Transparent" >        </activity>

这种方法是比较直接暴力的方法,但是解决不了问题。

方法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名字,例如下面这样:

<span style="font-family:Tahoma, Helvetica, Arial, 宋体, sans-serif;"><activity            android:name="com.vaecer.querycarparameter.ParameterListActivity"            android:configChanges="orientation|keyboardHidden"            android:label="@string/app_name" >        </activity></span>

这样设置以后,当屏幕旋转时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) {// TODO 屏幕发生旋转后触发的监听事件super.onConfigurationChanged(newConfig);Log.e("屏幕发生旋转后触发的监听事件", "" + newConfig);}


0 0
原创粉丝点击