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

一、简介

Some device configurations can change during runtime (such as screen orientation, keyboard availability, and language). When such a change occurs, Android restarts the runningActivity(onDestroy()is called, followed byonCreate()). 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系统会重启ActivityonDestroy()将被调用,随后再调用onCreate()来创建Activity).之所以设计为重启,主要是想通过重新加载你的应用程序来加载和新的配置环境相对应的资源,以便你的应用程序能很好的适配新的配置环境。

To properly handle a restart, it is important that your activity restores its previous state through the normalActivity lifecycle, in which Android callsonSaveInstanceState()before it destroys your activity so that you can save data about the application state. You can then restore the state duringonCreate()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 theActivity 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 statefulObjectto 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 theBundlethat the system saves for you with theonSaveInstanceState()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 statefulObjectwhen 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 theonRetainNonConfigurationInstance()method to return the object you would like to retain.重写onRetainNonConfigurationInstance()方法,在里面返回一个你想retain的对象
  2. When your activity is created again, callgetLastNonConfigurationInstance()to recover your object.在activity重生时,通过方法getLastNonConfigurationInstance()得到retian的对象,通过该对象恢复activity的状态。

When the Android system shuts down your activity due to a configuration change, it callsonRetainNonConfigurationInstance()between theonStop()andonDestroy()callbacks. In your implementation ofonRetainNonConfigurationInstance(), you can return anyObjectthat 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 implementonRetainNonConfigurationInstance()to return an object carrying your data and then retrieve the data when your activity starts again withgetLastNonConfigurationInstance(). For example:

 
   

@Override
public 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 theActivity, such as aDrawable, anAdapter, aViewor any other object that's associated with aContext. 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的引用,比如:aDrawable, anAdapter, aView或其他对当前Activity有引用的对象。否则会造成当前Activity无法被回收,造成内存泄露。

Then retrieve the data when your activity starts again:

 
   

@Override
public void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState );
setContentView ( R . layout . main );
final MyDataObject data = ( MyDataObject ) getLastNonConfigurationInstance ();
if ( data == null ) {
data = loadMyData ();
}
...
}

In this case, getLastNonConfigurationInstance() returns the data saved by onRetainNonConfigurationInstance() . 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.
publicObjectgetLastNonConfigurationInstance()
Since: API Level 1

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

Retrieve the non-configuration instance data that was previously returned byonRetainNonConfigurationInstance(). This will be available from the initialonCreate(Bundle)andonStart()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 shouldonlybe 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 normalonSaveInstanceState(Bundle)mechanism) even if this function returns null.

Returns
三、Handling the Configuration Change Yourself

If your application doesn't need to update resources during a specific configuration changeandyou have a performance limitation that requires you to avoid the activity restart, then you can declare that your activity handles the configuration change itself, which prevents the system from restarting your activity.

当某个运行时环境发生变化,如果你并不需要更新资源,或者因为性能的制约要求你避免重启Activity,你可以声明你自己处理这个运行时环境的变化,以避免系统restart你的activity.

Note:Handling the configuration change yourself can make it much more difficult to use alternative resources, because the system does not automatically apply them for you. This technique should be considered a last resort when you must avoid restarts due to a configuration change and is not recommended for most applications.

To declare that your activity handles a configuration change, edit the appropriate<activity>element in your manifest file to include theandroid:configChangesattribute with a value that represents the configuration you want to handle. Possible values are listed in the documentation for theandroid:configChangesattribute (the most commonly used values are"orientation"to prevent restarts when the screen orientation changes and"keyboardHidden"to prevent restarts when the keyboard availability changes). You can declare multiple configuration values in the attribute by separating them with a pipe|character.

为了声明你将自己处理运行时环境的变化,你需要在mainfest.xml文件中设置<activity>元素的android:configChanges属性,该属性所有可能的值都在android:configChanges的文档说明中(其中最常用的是关于屏幕旋转的"orientation"和键盘availability"keyboardHidden")。你可以声明多个configuration值,它们之间用|进行分割

For example, the following manifest code declares an activity that handles both the screen orientation change and keyboard availability change:

 
  

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

<wbr><div> <p style="line-height:19px; margin-top:0px; margin-bottom:15px; padding-top:0px; padding-bottom:0px; color:rgb(34,34,34); font-family:Roboto,sans-serif; background-color:rgb(249,249,249)"> Now, when one of these configurations change,<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace">MyActivity</code>does not restart. Instead, the<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace">MyActivity</code>receives a call to<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/app/Activity.html#onConfigurationChanged(android.content.res.Configuration)" style="color:rgb(37,138,175); line-height:25px; text-decoration:none">onConfigurationChanged()</a></code>. This method is passed a<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/content/res/Configuration.html" style="color:rgb(37,138,175); line-height:25px; text-decoration:none">Configuration</a></code>object that specifies the new device configuration. By reading fields in the<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/content/res/Configuration.html" style="color:rgb(37,138,175); line-height:25px; text-decoration:none">Configuration</a></code>, you can determine the new configuration and make appropriate changes by updating the resources used in your interface. At the time this method is called, your activity's<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/content/res/Resources.html" style="color:rgb(37,138,175); line-height:25px; text-decoration:none">Resources</a></code>object is updated to return resources based on the new configuration, so you can easily reset elements of your UI without the system restarting your activity.</p> <p style="line-height:19px; margin-top:0px; margin-bottom:15px; padding-top:0px; padding-bottom:0px; color:rgb(34,34,34); font-family:Roboto,sans-serif; background-color:rgb(249,249,249)"> 这样的话当屏幕旋转或键盘<span style="font-family:Roboto,sans-serif; color:#222222; line-height:22px"><span style="line-height:19px">availability发生变变化时,系统将不再重启Activity;取而代之的是这个Activity的函数</span></span><a rel="nofollow" href="http://developer.android.com/reference/android/app/Activity.html#onConfigurationChanged(android.content.res.Configuration)" style="color:rgb(37,138,175); line-height:22px; text-decoration:none; font-family:'courier new',courier,monospace; font-weight:bold">onConfigurationChanged()</a>将被系统调用。该函数传递一个<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/content/res/Configuration.html" style="color:rgb(37,138,175); line-height:22px; text-decoration:none">Configuration</a></code>对象,以说明运行时配置环境的变化。通过读该<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/content/res/Configuration.html" style="color:rgb(37,138,175); line-height:22px; text-decoration:none">Configuration</a></code>对象,你就能确定新的运行时配置环境,通过更新你的用户界面的资源来做合适的改变。当该方法被调用时,Activity的<a rel="nofollow" href="http://developer.android.com/reference/android/content/res/Resources.html" style="color:rgb(37,138,175); line-height:22px; text-decoration:none; font-family:'courier new',courier,monospace; font-weight:bold">Resources</a>对象已经是根据新的运行时配置环境而返回资源了。</p> <p style="line-height:19px; margin-top:0px; margin-bottom:15px; padding-top:0px; padding-bottom:0px; padding-left:10px; border-left-width:4px; border-left-style:solid; border-color:rgb(255,136,0); color:rgb(34,34,34); font-family:Roboto,sans-serif; background-color:rgb(249,249,249)"> <span style="line-height:25px">Caution:</span>Beginning with Android 3.2 (API level 13),<span style="line-height:25px">the "screen size" also changes</span>when the device switches between portrait and landscape orientation. Thus, if you want to prevent runtime restarts due to orientation change when developing for API level 13 or higher (as declared by the<a rel="nofollow" href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#min" style="color:rgb(37,138,175); line-height:25px; text-decoration:none"><code style="line-height:1.5; color:inherit; font-weight:bold; font-family:'courier new',courier,monospace">minSdkVersion</code></a>and<a rel="nofollow" href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#target" style="color:rgb(37,138,175); line-height:25px; text-decoration:none"><code style="line-height:1.5; color:inherit; font-weight:bold; font-family:'courier new',courier,monospace">targetSdkVersion</code></a>attributes), you must include the<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace">"screenSize"</code>value in addition to the<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace">"orientation"</code>value. That is, you must decalare<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace">android:configChanges="orientation|screenSize"</code>. However, if your application targets API level 12 or lower, then your activity always handles this configuration change itself (this configuration change does not restart your activity, even when running on an Android 3.2 or higher device).</p> <p style="line-height:19px; margin-top:0px; margin-bottom:15px; padding-top:0px; padding-bottom:0px; color:rgb(34,34,34); font-family:Roboto,sans-serif; background-color:rgb(249,249,249)"> 注意:从Android 3.2 (API level 13)开始,当设备的屏幕在横屏和竖屏之间进行切换时,<span style="line-height:22px">"screen size"</span>这个配置属性也会发生变化。因此从API level 13 or higher(as declared by the<a rel="nofollow" href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#min" style="color:rgb(37,138,175); line-height:22px; text-decoration:none"><code style="line-height:1.5; color:inherit; font-weight:bold; font-family:'courier new',courier,monospace">minSdkVersion</code></a>and<a rel="nofollow" href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#target" style="color:rgb(37,138,175); line-height:22px; text-decoration:none"><code style="line-height:1.5; color:inherit; font-weight:bold; font-family:'courier new',courier,monospace">targetSdkVersion</code></a>attributes)开始,如果你想屏幕旋转时,系统不重启Activity的话,你应该在<span style="line-height:21px; color:rgb(0,102,0); font-family:'courier new',courier,monospace"><strong>android:configChanges=</strong></span>的属性值<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace">"orientation"</code>上再加上<span style="line-height:21px; color:rgb(0,102,0); font-family:'courier new',courier,monospace"><strong>"screenSize"</strong></span>,比如<span style="line-height:21px; color:rgb(0,102,0); font-family:'courier new',courier,monospace"><strong>android:configChanges="orientation|screenSize"。</strong></span>然而如果你的应用程序的targets API level 12 或更低的,即使设备的是Android 3.2或更高,你不加<span style="line-height:21px; color:rgb(0,102,0); font-family:'courier new',courier,monospace"><strong>"screenSize"</strong></span>的话,系统也不会重启Activity,而是调用函数<a rel="nofollow" href="http://developer.android.com/reference/android/app/Activity.html#onConfigurationChanged(android.content.res.Configuration)" style="color:rgb(37,138,175); line-height:22px; text-decoration:none; font-family:'courier new',courier,monospace; font-weight:bold">onConfigurationChanged()</a>让你自己处理,屏幕改变这个运行时配置环境的变化。</p> <p style="line-height:19px; margin-top:0px; margin-bottom:15px; padding-top:0px; padding-bottom:0px; color:rgb(34,34,34); font-family:Roboto,sans-serif; background-color:rgb(249,249,249)"> For example, the following<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/app/Activity.html#onConfigurationChanged(android.content.res.Configuration)" style="color:rgb(37,138,175); line-height:25px; text-decoration:none">onConfigurationChanged()</a></code>implementation checks the current device orientation:</p> <p style="line-height:19px; margin-top:0px; margin-bottom:15px; padding-top:0px; padding-bottom:0px; color:rgb(34,34,34); font-family:Roboto,sans-serif; background-color:rgb(249,249,249)"> 以下是一个在<a rel="nofollow" href="http://developer.android.com/reference/android/app/Activity.html#onConfigurationChanged(android.content.res.Configuration)" style="color:rgb(37,138,175); line-height:22px; text-decoration:none; font-family:'courier new',courier,monospace; font-weight:bold">onConfigurationChanged()</a>中检查横竖屏的示例:</p> </div> <div> <div> <pre class="prettyprint" style="padding:2px; border:1px solid rgb(136,136,136)"><p style="margin-top:0px; margin-bottom:10px; padding-top:0px; padding-bottom:0px"></p><div><span class="lit" style="color:rgb(0,102,102)">@Override</span></div><div> <span class="lit" style="color:rgb(0,102,102)">public</span><span class="pln"> </span><span class="kwd" style="color:rgb(0,0,136)">void</span><span class="pln"> onConfigurationChanged</span><span class="pun" style="color:rgb(102,102,0)">(</span><span class="typ" style="color:rgb(102,0,102)">Configuration</span><span class="pln"> newConfig</span><span class="pun" style="color:rgb(102,102,0)">)</span><span class="pln"> </span><span class="pun" style="color:rgb(102,102,0)">{</span> </div><div> <span class="pln"> </span><span class="kwd" style="color:rgb(0,0,136)">super</span><span class="pun" style="color:rgb(102,102,0)">.</span><span class="pln">onConfigurationChanged</span><span class="pun" style="color:rgb(102,102,0)">(</span><span class="pln">newConfig</span><span class="pun" style="color:rgb(102,102,0)">);</span> </div><div> </div><div> <span class="pln"> </span><span class="com" style="color:rgb(136,0,0)">/* Checks the orientation of the screen*/</span> </div><div> <span class="pln"> </span><span class="kwd" style="color:rgb(0,0,136)">if</span><span class="pln"> </span><span class="pun" style="color:rgb(102,102,0)">(</span><span class="pln">newConfig</span><span class="pun" style="color:rgb(102,102,0)">.</span><span class="pln">orientation </span><span class="pun" style="color:rgb(102,102,0)">==</span><span class="pln"> </span><span class="typ" style="color:rgb(102,0,102)">Configuration</span><span class="pun" style="color:rgb(102,102,0)">.</span><span class="pln">ORIENTATION_LANDSCAPE</span><span class="pun" style="color:rgb(102,102,0)">)</span><span class="pln"> </span><span class="pun" style="color:rgb(102,102,0)">{</span> </div><div> <span class="pln"> </span><span class="typ" style="color:rgb(102,0,102)">Toast</span><span class="pun" style="color:rgb(102,102,0)">.</span><span class="pln">makeText</span><span class="pun" style="color:rgb(102,102,0)">(</span><span class="kwd" style="color:rgb(0,0,136)">this</span><span class="pun" style="color:rgb(102,102,0)">,</span><span class="pln"> </span><span class="str" style="color:rgb(0,136,0)">"landscape"</span><span class="pun" style="color:rgb(102,102,0)">,</span><span class="pln"> </span><span class="typ" style="color:rgb(102,0,102)">Toast</span><span class="pun" style="color:rgb(102,102,0)">.</span><span class="pln">LENGTH_SHORT</span><span class="pun" style="color:rgb(102,102,0)">).</span><span class="pln">show</span><span class="pun" style="color:rgb(102,102,0)">();</span> </div><div> <span class="pln"> </span><span class="pun" style="color:rgb(102,102,0)">}</span><span class="pln"> </span><span class="kwd" style="color:rgb(0,0,136)">else</span><span class="pln"> </span><span class="kwd" style="color:rgb(0,0,136)">if</span><span class="pln"> </span><span class="pun" style="color:rgb(102,102,0)">(</span><span class="pln">newConfig</span><span class="pun" style="color:rgb(102,102,0)">.</span><span class="pln">orientation </span><span class="pun" style="color:rgb(102,102,0)">==</span><span class="pln"> </span><span class="typ" style="color:rgb(102,0,102)">Configuration</span><span class="pun" style="color:rgb(102,102,0)">.</span><span class="pln">ORIENTATION_PORTRAIT</span><span class="pun" style="color:rgb(102,102,0)">){</span> </div><div> <span class="pln"> </span><span class="typ" style="color:rgb(102,0,102)">Toast</span><span class="pun" style="color:rgb(102,102,0)">.</span><span class="pln">makeText</span><span class="pun" style="color:rgb(102,102,0)">(</span><span class="kwd" style="color:rgb(0,0,136)">this</span><span class="pun" style="color:rgb(102,102,0)">,</span><span class="pln"> </span><span class="str" style="color:rgb(0,136,0)">"portrait"</span><span class="pun" style="color:rgb(102,102,0)">,</span><span class="pln"> </span><span class="typ" style="color:rgb(102,0,102)">Toast</span><span class="pun" style="color:rgb(102,102,0)">.</span><span class="pln">LENGTH_SHORT</span><span class="pun" style="color:rgb(102,102,0)">).</span><span class="pln">show</span><span class="pun" style="color:rgb(102,102,0)">();</span> </div><div> <span class="pln"> </span><span class="pun" style="color:rgb(102,102,0)">}</span> </div><div><span class="pun" style="color:rgb(102,102,0)">}</span></div><p style="margin-top:0px; margin-bottom:10px; padding-top:0px; padding-bottom:0px"></p></pre> </div> <div> <p style="line-height:19px; margin-top:0px; margin-bottom:15px; padding-top:0px; padding-bottom:0px; color:rgb(34,34,34); font-family:Roboto,sans-serif; background-color:rgb(249,249,249)"> The<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/content/res/Configuration.html" style="color:rgb(37,138,175); line-height:25px; text-decoration:none">Configuration</a></code>object represents all of the current configurations, not just the ones that have changed. Most of the time, you won't care exactly how the configuration has changed and can simply re-assign all your resources that provide alternatives to the configuration that you're handling. For example, because the<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/content/res/Resources.html" style="color:rgb(37,138,175); line-height:25px; text-decoration:none">Resources</a></code>object is now updated, you can reset any<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/widget/ImageView.html" style="color:rgb(37,138,175); line-height:25px; text-decoration:none">ImageView</a></code>s with<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/widget/ImageView.html#setImageResource(int)" style="color:rgb(37,138,175); line-height:25px; text-decoration:none">setImageResource()</a></code>and the appropriate resource for the new configuration is used (as described in<a rel="nofollow" href="http://developer.android.com/guide/topics/resources/providing-resources.html#AlternateResources" style="color:rgb(37,138,175); line-height:25px; text-decoration:none">Providing Resources</a>).</p> <p style="line-height:19px; margin-top:0px; margin-bottom:15px; padding-top:0px; padding-bottom:0px; color:rgb(34,34,34); font-family:Roboto,sans-serif; background-color:rgb(249,249,249)"> <a rel="nofollow" href="http://developer.android.com/reference/android/app/Activity.html#onConfigurationChanged(android.content.res.Configuration)" style="color:rgb(37,138,175); line-height:22px; text-decoration:none; font-family:'courier new',courier,monospace; font-weight:bold">onConfigurationChanged()</a>中的传人的参数<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/content/res/Configuration.html" style="color:rgb(37,138,175); line-height:22px; text-decoration:none">Configuration</a></code>对象代表的是当前运行时的所有配置,而不仅仅是改变了的运行时配置。大多数时,你并不用关心配置环境是如果变化的,你仅仅需要的是re-assign所有的resources。比如因为<a rel="nofollow" href="http://developer.android.com/reference/android/content/res/Resources.html" style="color:rgb(37,138,175); line-height:22px; text-decoration:none; font-family:'courier new',courier,monospace; font-weight:bold">Resources</a>对象已经是根据新的运行时配置环境而返回资源了,对于<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/widget/ImageView.html" style="color:rgb(37,138,175); line-height:22px; text-decoration:none">ImageView</a></code>s你只可以直接调用<a rel="nofollow" href="http://developer.android.com/reference/android/widget/ImageView.html#setImageResource(int)" style="color:rgb(37,138,175); line-height:22px; text-decoration:none; font-family:'courier new',courier,monospace; font-weight:bold">setImageResource()</a>来进行资源的更新</p> <p style="line-height:19px; margin-top:0px; margin-bottom:15px; padding-top:0px; padding-bottom:0px; color:rgb(34,34,34); font-family:Roboto,sans-serif; background-color:rgb(249,249,249)"> Notice that the values from the<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/content/res/Configuration.html" style="color:rgb(37,138,175); line-height:25px; text-decoration:none">Configuration</a></code>fields are integers that are matched to specific constants from the<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/content/res/Configuration.html" style="color:rgb(37,138,175); line-height:25px; text-decoration:none">Configuration</a></code>class. For documentation about which constants to use with each field, refer to the appropriate field in the<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/content/res/Configuration.html" style="color:rgb(37,138,175); line-height:25px; text-decoration:none">Configuration</a></code>reference.</p> <p style="line-height:19px; margin-top:0px; margin-bottom:15px; padding-top:0px; padding-bottom:0px; padding-left:10px; border-left-width:4px; border-left-style:solid; border-color:rgb(37,138,175); color:rgb(34,34,34); font-family:Roboto,sans-serif; background-color:rgb(249,249,249)"> <span style="line-height:25px">Remember:</span>When you declare your activity to handle a configuration change, you are responsible for resetting any elements for which you provide alternatives. If you declare your activity to handle the orientation change and have images that should change between landscape and portrait, you must re-assign each resource to each element during<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/app/Activity.html#onConfigurationChanged(android.content.res.Configuration)" style="color:rgb(37,138,175); line-height:25px; text-decoration:none">onConfigurationChanged()</a></code>.</p> <p style="line-height:19px; margin-top:0px; margin-bottom:15px; padding-top:0px; padding-bottom:0px; color:rgb(34,34,34); font-family:Roboto,sans-serif; background-color:rgb(249,249,249)"> If you don't need to update your application based on these configuration changes, you can instead<span style="line-height:25px">not</span>implement<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/app/Activity.html#onConfigurationChanged(android.content.res.Configuration)" style="color:rgb(37,138,175); line-height:25px; text-decoration:none">onConfigurationChanged()</a></code>. In which case, all of the resources used before the configuration change are still used and you've only avoided the restart of your activity. However, your application should always be able to shutdown and restart with its previous state intact, so you should not consider this technique an escape from retaining your state during normal activity lifecycle. Not only because there are other configuration changes that you cannot prevent from restarting your application, but also because you should handle events such as when the user leaves your application and it gets destroyed before the user returns to it.</p> <p style="line-height:19px; margin-top:0px; margin-bottom:15px; padding-top:0px; padding-bottom:0px; color:rgb(34,34,34); font-family:Roboto,sans-serif; background-color:rgb(249,249,249)"> 对于所有的运行时配置环境变化,你如果都不想你的应用程序因此而做任何的改变, 你根本就可以不用实现<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/app/Activity.html#onConfigurationChanged(android.content.res.Configuration)" style="color:rgb(37,138,175); line-height:22px; text-decoration:none">onConfigurationChanged()</a></code>.这样的话,当任何运行时配置环境发生时,你的Activity就不会做任何改变。然而你的应用程序应该能被关闭然后重启回到和以前一样的状态。因此前面介绍的技术并不是用来逃避Activity被关闭然后重启回到以前状态的。这并不仅仅是因为还没有阻止因其他的配置变化而重启Activity;这也是因你在用户离开你的应用程序然后该应用程序结束后又试图回到你的应用程序这种场景下你其实是不得不处理Activity关闭然后重启回到和以前一样的状态这么一个event的</p> <p style="line-height:19px; margin-top:0px; margin-bottom:15px; padding-top:0px; padding-bottom:0px; color:rgb(34,34,34); font-family:Roboto,sans-serif; background-color:rgb(249,249,249)"> For more about which configuration changes you can handle in your activity, see the<a rel="nofollow" href="http://developer.android.com/guide/topics/manifest/activity-element.html#config" style="color:rgb(37,138,175); line-height:25px; text-decoration:none"><code style="line-height:1.5; color:inherit; font-weight:bold; font-family:'courier new',courier,monospace">android:configChanges</code></a>documentation and the<code style="line-height:1.5; color:rgb(0,102,0); font-weight:bold; font-family:'courier new',courier,monospace"><a rel="nofollow" href="http://developer.android.com/reference/android/content/res/Configuration.html" style="color:rgb(37,138,175); line-height:25px; text-decoration:none">Configuration</a></code>class.</p> </div> <wbr><div>结束</div> </wbr> </div> </wbr>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值