android 处理运行时改变 开发文档翻译
由于本人英文能力实在有限,不足之初敬请谅解
本博客只要没有注明“转”,那么均为原创,转贴请注明本博客链接链接
其他系列的翻译
android activity开发文档翻译 - 1 - 基础篇
android activity开发文档翻译 - 2 - 生命周期篇
android task与back stack 开发文档翻译 - 1
android task与back stack 开发文档翻译 - 2
android task与back stack 开发文档翻译 - 3
本系列并没有对原文100%翻译,也没有100%的贴出原文
Handling Runtime Changes
处理运行时改变
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重启运行中的Activity(调用onDestroy(),onCreate()紧跟其后)
重启行为被设计用于帮助你的应用使用匹配新的设备配置的恰当资源,自动的重新加载你的应用适配新的配置
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() or onRestoreInstanceState().
恰当的处理一个重启,你的activity通过正常的Activity生命周期(Android在销毁你的activity之前调用onSaveInstanceState(),这样你就能保存关于应用状态的数据了)恢复其之前的状态是很重要的。
然后你可以在onCreate()或者onRestoreInstanceState()期间恢复状态。
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:
然而,你可能遇到这样一种情况:重启应用并且恢复大量重要数据变得奢侈并且建立一个很糟的用户体验
这种情况下,你有两种选择:
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.
1.在配置改变期间,保持一个对象
当一个配置改变时,允许你的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 manually update your activity as necessary.
2.你自己处理配置改变
在某个配置改变期间,阻止系统重启你的activity,但是当配置改变时收到一个回调,这样如果有必要的话就能手动的更新你的activity
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要求你恢复大量数据,重新建立网络连接,或者执行其他大量的工作,那么一个由配置改变引起的完整的重启可能会导致一个很慢的用户体验。
也许对你来说,使用系统在onSaveInstanceState()回调中为你保存的Bundle恢复你的activity状态是不可能的 - 它并不是为传递大对象(比如bitmap)和数据内序列化和反序列化,那些可消耗大量内存并且使得配置改变的很慢的数据。
这种情况,当配置改变导致你的activity重启时,你可以通过保持一个有状态的对象减轻重新初始化你的activity的负担
To retain an object during a runtime configuration change:
在运行时配置改变期间,保持一个对象
Override the onRetainNonConfigurationInstance() method to return the object you would like to retain.
When your activity is created again, call getLastNonConfigurationInstance() to recover your object.
When the Android system shuts down your activity due to a configuration change, it calls onRetainNonConfigurationInstance() 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.
覆盖onRetainNonConfigurationInstance()方法返回你想要保持的对象
当你的activity重新建立时,调用getLastNonConfigurationInstance()来恢复你的对象
当Android系统因为一个配置改变而关闭你的activity时,它会在onStop()和onDestroy()回调之间调用onRetainNonConfigurationInstance()。
在你的onRetainNonConfigurationInstance()实现中,你可以返回任何在配置改变之后有效的恢复你的状态所需要的对象
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 with getLastNonConfigurationInstance().
For example:
一个如果你的应用从web加载大量数据的情况是有价值的。
如果用户改变设备方向并且activity重启,你的应用必须重新获取数据,这就可能很慢。
取而代之,你能做的是实现onRetainNonConfigurationInstance()来返回持有你的数据并且之后当你的activity通过getLastNonConfigurationInstance()再次启动时,恢复你的数据。
例如:
@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 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.)
注意:你可以返回任何对象,但是你不能传递一个绑定到activity上的对象,比如一个Drawable、Adapter、View或者任何其他与Context关联的对象
如果你这样做了,这将导致原始activity实例所有view和resource泄漏(资源泄漏意味着你的应用保持一个他们的引用,并且他们不能被垃圾回收,所以会丢失大量内存。)
Then retrieve the data when your activity starts again:
然后当你的activity重启的时候恢复数据
@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.
这种情况下,getLastNonConfigurationInstance()返回通过onRetainNonConfigurationInstance()保存的数据
如果数据为null(当activity因为任何与配置改变不同的原因启动时会发生)那么这段代码从原始资源加载数据对象。
Handling the Configuration Change Yourself
你自己处理配置改变
If your application doesn't need to update resources during a specific configuration change and you 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重启,那么你可以声明你的activity自己处理配置改变,阻止系统重启你的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 the android:configChanges attribute with a value that represents the configuration you want to handle.
Possible values are listed in the documentation for the android:configChanges attribute (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.
为了声明你的activity处理一个配置改变,在你的manifest文件中编辑适当的<activity>元素来包含值为你想要处理的配置的android:configChanges属性
可用值在android:configChanges属性文档中列出。(最常用的属性是"orientation"来阻止当屏幕方向改变时的重启,和"keyboardHidden"来阻止当键盘可用性改变时的重启)
你可以在属性中通过“|”声明多个配置值。
For example, the following manifest code declares an activity that handles both the screen orientation change and keyboard availability change:
例如,下面的manifest代码声明一个activity处理屏幕方向改变和键盘可用性改变。
<activity android:name=".MyActivity" android:configChanges="orientation|keyboardHidden" android:label="@string/app_name">
Now, when one of these configurations change, MyActivity does not restart.
Instead, the MyActivity receives a call to onConfigurationChanged().
This method is passed a Configuration object that specifies the new device configuration.
By reading fields in the Configuration, 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 Resources 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.
现在,当一个这些配置中一个改变时,MyActivity不会重启。
取而代之,MyActivity收到一个onConfigurationChanged()调用。
这个方法传递一个Configuration对象,其指定了新的设备配置。
通过读取Configuration的字段,你可以推断出新配置并且通过更新你接口中使用的资源做出适当的改变。
在这个方法调用的时候,你的activity的Resources对象被更新为基于新配置的返回资源,所以你可以轻松的在系统没有重启你activity情况下重置你的UI元素
Caution: Beginning with Android 3.2 (API level 13), the "screen size" also changes 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 minSdkVersion and targetSdkVersion attributes), you must include the "screenSize" value in addition to the "orientation" value.
That is, you must decalare android:configChanges="orientation|screenSize".
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).
注意:从Android 3.2(API level 13)开始,当设备在横向和纵向之间切换时,"screen size"也会改变。
因此,当你使用API level 13或更高级别API开发时(如通过minSdkVersion和targetSdkVersion声明一样),如果你想要阻止运行时方向改变导致的重启,你必须在“orientation”之外还要包含"screenSize"
也就是说,你必须声明android:configChanges="orientation|screenSize"
然而,如果你的应用目标API级别为12或者更低,那么你的activity总是自己处理这个配置改变(这个配置改变不会重启你的activity,甚至当运行在Android 3.2或者更高版本的设备也是这样)
For example, the following onConfigurationChanged() implementation checks the current device orientation:
例如,下面onConfigurationChanged()的实现检查当前设备的方向。
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show(); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show(); } }
The Configuration 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 Resources object is now updated, you can reset any ImageViews with setImageResource() and the appropriate resource for the new configuration is used (as described in Providing Resources).
Configuration对象描述所有当前配置,并不只是那些改变的配置
大多数时候,你不需要关心配置到底是如何改变的,配置如何能简单的重新分配你所有的用来提供替代配置的你正在处理的资源。
例如,因为Resources对象正被更新,你可以通过setImageResource()和用于新配置的适当资源重置任何ImageViews。
Notice that the values from the Configuration fields are integers that are matched to specific constants from the Configuration class.
For documentation about which constants to use with each field, refer to the appropriate field in the Configuration reference.
注意Configuration字段类型是integer,与Configuration类中指定常量相匹配。
关于每一个字段使用哪一个常量的文档,参看Configuration参考中的适当的字段。
Remember: 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 onConfigurationChanged().
记住:当你声明你的activity来处理一个配置改变时,你要为任何你提供可选择的元素的重启负责。
如果你声明你的activity来处理方向改变,并且有图片应该在横向和纵向之间改变,你必须在onConfigurationChanged()期间为每一个元素重新分配每一个资源。
If you don't need to update your application based on these configuration changes, you can instead not implement onConfigurationChanged().
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.
如果你不需要基于这些配置改变更新你应用,你可以选择不去实现onConfigurationChanged()
在这种情况下,配置改变之前所有使用的资源仍然被使用,你已经避免了你的activity重启
然而,你的应用应该有能力关闭并且使用它之前完整状态重启,所以你不应该认为这种技术是在正常的activity声明周期期间保持你的状态的一种逃避。
不仅因为其他你不能阻止重启你应用的配置改变,也因为你应该处理像当用户离开你的应用和用户返回到它之前被销毁的事件。
最后列出你可以在你的activity处理的配置改变,来自android:configChanges文档。
"mcc " |
The IMSI mobile country code (MCC) has changed — a SIM has been detected and updated the MCC. |
"mnc " |
The IMSI mobile network code (MNC) has changed — a SIM has been detected and updated the MNC. |
"locale " |
The locale has changed — the user has selected a new language that text should be displayed in. |
"touchscreen " |
The touchscreen has changed. (This should never normally happen.) |
"keyboard " |
The keyboard type has changed — for example, the user has plugged in an external keyboard. |
"keyboardHidden " |
The keyboard accessibility has changed — for example, the user has revealed the hardware keyboard. |
"navigation " |
The navigation type (trackball/dpad) has changed. (This should never normally happen.) |
"screenLayout " |
The screen layout has changed — this might be caused by a different display being activated. |
"fontScale " |
The font scaling factor has changed — the user has selected a new global font size. |
"uiMode " |
The user interface mode has changed — this can be caused when the user places the device into a desk/car dock or when the the night mode changes. See UiModeManager . Introduced in API Level 8. |
"orientation " |
The screen orientation has changed — the user has rotated the device.
Note: If your application targets API level 13 or higher (as declared by the |
"screenSize " |
The current available screen size has changed. This represents a change in the currently available size, relative to the current aspect ratio, so will change when the user switches between landscape and portrait. 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).
Added in API level 13. |
"smallestScreenSize " |
The physical screen size has changed. This represents a change in size regardless of orientation, so will only change when the actual physical screen size has changed such as switching to an external display. A change to this configuration corresponds to a change in the smallestWidth configuration. 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).
Added in API level 13. |
原文地址如下,英文水平实在有限,希望拍砖同时能给予指正。
http://developer.android.com/guide/topics/resources/runtime-changes.html
转贴请保留以下链接
本人blog地址
上一篇: 大话重构连载4:大布局与小步快跑
下一篇: 我是怎样改善遗留系统的
推荐阅读
-
Android Interface Definition Language (AIDL) android接口定义语言 开发文档翻译 - 2
-
粮草先行——Android折叠屏开发技术点番外篇之运行时变更处理原则
-
android - 为安全而设计 - 1 - 开发文档翻译
-
android 管理Bitmap内存 - 开发文档翻译
-
Android Interface Definition Language (AIDL) android接口定义语言 开发文档翻译 - 2
-
android 缓存Bitmap - 开发文档翻译
-
android 有效加载大Bitmap - 开发文档翻译
-
android 在你的UI中显示Bitmap - 开发文档翻译
-
android 高效显示Bitmap - 开发文档翻译
-
android 在UI线程之外处理Bitmap - 开发文档翻译