读书人

Android中运行时配备环境的改变

发布时间: 2012-10-12 10:17:04 作者: rapoo

Android中运行时配置环境的改变
原文:http://developer.android.com/guide/topics/resources/runtime-changes.html一、简介

Some device configurations can change during runtime (such as screen orientation, keyboard availability, and language). When such a change occurs, Android restarts the running Activity (onDestroy()is called, followed by onCreate()). The restart behavior is designed to help your application adapt to new configurations by automatically reloading your application with alternative resources that match the new device configuration.

Android中,当应用程序运行的时,设备的配置环境也许会发生变化(比如屏幕的旋转,键盘可用性的改变,语言的改变)。但是这些变化发生时,Android系统会重启Activity(onDestroy()将被调用,随后再调用onCreate()来创建Activity).之所以设计为重启,主要是想通过重新加载你的应用程序来加载和新的配置环境相对应的资源,以便你的应用程序能很好的适配新的配置环境。

To properly handle a restart, it is important that your activity restores its previous state through the normal Activity lifecycle, in which Android calls onSaveInstanceState() before it destroys your activity so that you can save data about the application state. You can then restore the state during onCreate() oronRestoreInstanceState().

为了很好的处理Activity的重启,我们应该在Activity销毁前的系统回调函数中onSaveInstanceState() 保存其状态,然后在其重新被构建时的系统回调函数 onCreate() oronRestoreInstanceState()中,根据前面保存的状态来进行相应的设置,以便还原到重启前的相应状态。关于onSaveInstanceState() 和onRestoreInstanceState()更多的内容可以参考《关于onSaveInstanceState(Bundle)和onRestoreInstanceState(Bundle)》

To test that your application restarts itself with the application state intact, you should invoke configuration changes (such as changing the screen orientation) while performing various tasks in your application. Your application should be able to restart at any time without loss of user data or state in order to handle events such as configuration changes or when the user receives an incoming phone call and then returns to your application much later after your application process may have been destroyed. To learn how you can restore your activity state, read about the Activity lifecycle.

为了测试你的应用程序的Activity是否能够很好的进行重启,你应该在你的应用程式执行各类任务时都尝试改变配置环境,检查Activity是否能很好的进行重生。为了很好的处理运行时配置环境的变化或像用户有个来电然后在的应用程序的进程已经销毁后试图回到的你应用程序这种场景,你的应用程序应该在任何时候都能够很好的被重启,而不丢失任何用户数据和用户状态。

However, you might encounter a situation in which restarting your application and restoring significant amounts of data can be costly and create a poor user experience. In such a situation, you have two other options:

然而你可能面临如下问题:重启一个Activity并重新恢复其相关的数据非常的昂贵,这样可能造成用户体验非常的不好。这时你有以下两个选择:

  1. Retain an object during a configuration change

    Allow your activity to restart when a configuration changes, but carry a stateful Object to the new instance of your activity.在运行配置环境发生变化时,允许Activity进行重启,但是携带一个能表明Activity此时状态的对象到新的Activity对象

  2. Handle the configuration change yourself

    Prevent the system from restarting your activity during certain configuration changes, but receive a callback when the configurations do change, so that you can manuall.但某些配置发生变化时,阻止系统重启你的activity,而且只是在回调函数onConfigurationChanged() i中相应的处理

、Retaining an Object During a Configuration Change

If restarting your activity requires that you recover large sets of data, re-establish a network connection, or perform other intensive operations, then a full restart due to a configuration change might be a slow user experience. Also, it might not be possible for you to completely restore your activity state with the Bundle that the system saves for you with the onSaveInstanceState() callback—it is not designed to carry large objects (such as bitmaps) and the data within it must be serialized then deserialized, which can consume a lot of memory and make the configuration change slow. In such a situation, you can alleviate the burden of reinitializing your activity by retaining a stateful Object when your activity is restarted due to a configuration change.

如果重启一个activity需要恢复大量的数据,或需要重新进行网络链接操作,或其他一些敏感的操作,这时因为运行时配置环境变化而重启activity就可能降低用户体验。另外可能完全通过的回调函数onSaveInstanceState() 的Bundle可能也无法完全保存activity此时的状态。Bundle 本身并不是设计来携带大型对象(比如 bitmaps)的,它携带的数据必须是可序列化和反序列化;如果携带大型对象的话,将消耗大量的内存并降低应用程序对运行时环境变化的相应速度。在这种情形下,可以在你的应用程序因为运行时环境发生变化而需重启时,请求系统retian一个代表activity状态的对象以便activity重生时使用,这样可以达到优化activity重生的目的。

To retain an object during a runtime configuration change:

为了在运行时环境发生变化时,retain一个对象需要做以下两步操作。

  1. Override the onRetainNonConfigurationInstance() method to return the object you would like to retain.重写onRetainNonConfigurationInstance() 方法,在里面返回一个你想retain的对象
  2. When your activity is created again, call getLastNonConfigurationInstance() to recover your object.在activity重生时,通过方法 getLastNonConfigurationInstance() 得到retian的对象,通过该对象恢复activity的状态。

When the Android system shuts down your activity due to a configuration change, it callsonRetainNonConfigurationInstance() between the onStop() and onDestroy() callbacks. In your implementation of onRetainNonConfigurationInstance(), you can return any Object that you need in order to efficiently restore your state after the configuration change.当系统因为运行时环境发生变化而关闭你的activity时,系统会在activity的生命周期函数onStop() 和onDestroy()之间调用函数onRetainNonConfigurationInstance() ,你可以重写该函数,在里面返回一个你想retain的对象。在activity重生时,通过方法 getLastNonConfigurationInstance() 得到retian的对象,通过该对象恢复activity的状态。

A scenario in which this can be valuable is if your application loads a lot of data from the web. If the user changes the orientation of the device and the activity restarts, your application must re-fetch the data, which could be slow. What you can do instead is implement onRetainNonConfigurationInstance() to return an object carrying your data and then retrieve the data when your activity starts again withgetLastNonConfigurationInstance(). For example:

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

Caution: While you can return any object, you should never pass an object that is tied to the Activity, such as a Drawable, an Adapter, a View or any other object that's associated with a Context. If you do, it will leak all the views and resources of the original activity instance. (Leaking resources means that your application maintains a hold on them and they cannot be garbage-collected, so lots of memory can be lost.)

注意:你通过onRetainNonConfigurationInstance() 返回的对象不能有对当前Activity的引用,比如:a Drawable, an Adapter, a View或其他对当前Activity有引用的对象。否则会造成当前Activity无法被回收,造成内存泄露。

Then retrieve the data when your activity starts again:

@Overridepublicvoid(Bundle){super.();(..);finalMyDataObject=(MyDataObject)();if(==null){=();}...}

In this case, getLastNonConfigurationInstance() returns the data saved byonRetainNonConfigurationInstance(). If data is null (which happens when the activity starts due to any reason other than a configuration change) then this code loads the data object from the original source.

public Object getLastNonConfigurationInstance ()Since: API Level 1

This method is deprecated.
Use the new Fragment API setRetainInstance(boolean) instead; this is also available on older platforms through the Android compatibility package.

Retrieve the non-configuration instance data that was previously returned by onRetainNonConfigurationInstance(). This will be available from the initialonCreate(Bundle) and onStart() calls to the new instance, allowing you to extract any useful dynamic state from the previous instance.

该方法将返回onRetainNonConfigurationInstance()中返回给系统用于retain的对象,该方法在Activity重生时的onCreate(Bundle)onStart() 生命周期之间有效。因为onRestoreInstanceState()在之后onStart() 调用,所以 getLastNonConfigurationInstance() 在方法onRestoreInstanceState()中使用无效。

Note that the data you retrieve here should only be used as an optimization for handling configuration changes. You should always be able to handle getting a null pointer back, and an activity must still be able to restore itself to its previous state (through the normal onSaveInstanceState(Bundle) mechanism) even if this function returns null.

Returns
读书人网 >Android

热点推荐