某些设备配置能够在运行期间进行改变(如屏幕的方向、键盘可用性、语言等)。当这样的改变发生时,Android会重启正在运行的Activity(onDestroy()回调之后,紧跟着调用onCreate()回调方法)。设计这种重启行为有助于应用程序通过重启,重新载入跟新设备配置相匹配的可选资源。
要正确的处理重启,重要的是要恢复Activity之前的生存周期状态,因此在Activity被销毁之前,Android会调用onSaveInstanceState()回调方法来保存应用程序相关的状态数据。这样在Activity的onCreate()或onRestoreInstanceState()被调用期间就可以恢复之前的状态了。
要测试应用程序重启后的状态的完整性,就应该在程序运行时改变设备配置(如改变屏幕方向)。应用程序应该在处理配置改变、电话接入等事件的任何时候,都能够重启而且不丢失用户数据和状态。要了解Activity状态是如何被恢复的,请阅读Activity的生存周期。
但是,可能会遇到在重启应用程序时要恢复大量数据的情况,这时可能会给用户带来不好的用户体验。这样情况,有两个选择:
1.在配置改变期间保留一个对象。
当配置改变时,允许Activity重启,但是要把状态对象携带给Activity新的实例。
2.自行处理配置的变化
在某个配置改变期间,防止系统重启Activity,但是要在配置改变时接收一个回调方法,以便在必要时手动的更新Activity。
在配置变化期间保留一个对象
如果在重启Activity时,要求恢复大数据集、重建网络连接、或执行其他的敏感操作,那么由于配置的改变完全重启会降低用户体验。此外,系统也不可能用onSaveInstanceState()回调方法的Bundle对象来完整的保存要恢复的数据,因为Bundle对象没有被设计用来携带大对象(如位图)和大数据,这样导致Bundle对象在系列化和随后的反系列化时要占用大量的内存,从而导致配置改变缓慢。这种情况下,可以选择保留一个状态对象来减轻恢复Activity重启时的负担。
保留运行期间配置改变对象的方法如下:
1.重写onRetainNonConfigurationInstance()回调方法,它会返回希望保留的对象。
2.在Activity被重建时,调用getLastNonConfigurationInstance()方法来恢复这个对象。
当Android系统由于配置的变化关掉Activity时,它会在onStop()回调和onDestroy()之间调用onRetainNonConfigurationInstance()回调方法。在onRetainNonConfigurationInstance()回调的实现中,为了在配置变化之后能够有效的恢复状态,它可以返回任意任何需要的对象。
如果应用程序要从网络上加载数据,这样做就很有价值。如果用户改变了设备的方向,并且Activity重启了,应用程序就必须重新获取数据,这样会很慢。因此可以实现onRetainNonConfigurationInstance()方法,让它返回一个带有数据的对象,然后再Activity被重启时,再用getLastNonConfigurationInstance()方法来获取这个被保留的对象,例如:
@Override
public
Object onRetainNonConfigurationInstance()
{
final
MyDataObject data
= collectMyLoadedData();
return data;
}
警告:在返回对象时,不要带有跟Activity绑定的对象,如Drawable、Adapter、View或其他跟Context关联的对象。如果这样做了,会导致最初的Activity实例的所有View对象和资源泄漏(泄漏资源意味着应用程序占用了这些资源,因而不能被作为垃圾来回收,这样就会导致大量的内存占用)。
Activity重启时,恢复数据的方法:
@Override
public
void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final
MyDataObject data
= (MyDataObject) getLastNonConfigurationInstance();
if
(data ==
null) {
data = loadMyData();
}
...
}
这个例子中,getLastNonConfigurationInstance()方法返回被onRetainNonConfigurationInstance()方法保存的数据。如果data对象是null(在由于配置改变以外的其他原因而导致的Activity重启时,会发生这种情况),那么代码就会从初始资源中装载数据对象。
自行处理配置变化
如果在特定的配置变化期间,应用程序不需要更新资源,并且由于性能的限制,要求避免Activity的重启,那么可以声明让Activity自行处理配置的变化,从而防止系统重启Activity。
注意:自行处理配置的变化使得使用可选资源更加困难,因为系统不能自动的应用它们。这种技术应该在必须避免Activity重启(由于配置的变化)时,最后才考虑使用,并且大数应用程序不推荐使用。
要让Activity处理配置的变化,就要编辑清单文件中相应的<activity>元素,让它包含android:configChanges属性,这个属性值代表了要处理的配置。可能的值在android:configChanges属性文档中被列出(最常使用的值时“orientation”和“keyboardHidden”,orientation用于在屏幕方向变化时,防止Activity的重启;keyboardHidden用于在键盘的可用性发生变化时,防止Activity重启)。通过用管道符“|”分离,可以给这个属性声明多个配置值。
例如,下列清单代码就声明了一个自行处理屏幕方向变化和键盘可用性变化的Activity:
<activityandroid:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name">
通过上述声明,当这些配置中其中之一发生变化时,MyActivity就不会重启了,相反,MyActivity会接收onConfigurationChanged()方法的回调。这个方法被传入了一个Configuration对象,它指定了新的设备配置。通过读取Configuration对象中的字段,就能够判断新的配置,并通过更新界面中使用的资源来进行对应的改变。在调用这个方法时,Activity的Resources对象会被基于新配置所返回的资源更新,因此不用系统重启Activity,就能够容易的重设UI元素。
警告:从Android3.2(API级别13)开始,设备在纵向和横向之间切换时,“屏幕尺寸”也会发生改变。因此在使用API级别13或更高版本开发时,如果想要在运行时防止由于方向的变化而导致的重启,就必须在android:configChanges的属性值中包含“screenSize”。也就是说,必须声明android:configChanges=”orientation|screenSize”。但是,如果应用的目标平台是API级别12或更低版本,那么Activity就会始终自行处理配置的变化(这样配置的变化就不会重启Activity,即使是在Android3.2或更高版本的设备上运行,也不会重启Activity)。
例如,下面的onConfigurationChanged()方法实现了对当前设备方向的检查:
@Override
publicvoid 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();
}elseif(newConfig.orientation
==Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this,"portrait",Toast.LENGTH_SHORT).show();
}
}
Configuration对象代表了所有的当前配置,不仅仅针对改变的那个配置。大多数时候,不必关注配置是如何变化的,只需把提供的可选资源重新分配给正在处理的配置就可以了。例如,因为Resources对象的更新,就要用setImageResource()方法重设所有ImageView对象,并且给新的配置使用适当的资源。
我们注意到,来自Configuration字段的值是整数,它要跟Configuration类中指定的常量进行匹配。关于这些常量的说明,请参考Configuration类说明。
记住:当声明了要Activity自行处理配置变化时,就要手动的负责重设Activity中的任何UI元素。如果声明了Activity要处理方向的变化,并且在横向和纵向之间切换时有图标的变化,那么在onConfigurationChanged()执行期间,就应该重新分配每个资源。
如果不需要基于这些配置变化来更新应用程序,就不必实现onConfigurationChanged()方法。这样,所有的在配置变化之前使用的资源会在变化之后依然使用,仅仅是避免了Activity的重启。但是,应用程序使用能够关闭并用之前完整的状态来重启,因此,在普通Activity的生存期间不应该考虑使用这种技术,这不仅是因为这样不能阻止其他配置变化所导致的应用程序重启,而且也因为应该处理诸如用户离开应用程序、用户返回应用之前获取被销毁的状态等事件。
关于在Activity中能够处理的配置变化的更多信息,请看android:configChanges文档和Configuration类。
分享到:
相关推荐
FANUC_Robot_R-30iA_控制装置_Handing_Tool_操作说明书。详细的介绍了机器人的基本操作
spring-resource-handling, Spring Framework 4.1资源处理示例 spring-资源处理 这里应用程序演示 Spring Framework 4.1中的新资源处理功能。 它最初是为在 4.1中讨论资源而开发的,在 SpringOne2GX 2014中讨论。...
handing event
LR Handing Tool操作说明书
handing emi in switch mode power supply in design
第11章 异常处理(exception handing) 154 11.1 try-catch语句 154 11.2 Exception类的种类 157 11.3 可抛出异常的方法 158 11.4 自定义异常 161 11.5 巩固练习 162 第12章 常用API之一 164 12.1 ...
发那科工业机器人fanuc R-30iB操作说明书(基本操作篇).PDF.pdf
fluent菜鸟必读,综合了网上关于fluent的各种问题,包括软件安装,模型的建立和导入,网格化,几何经典的例子以及最后的后处理等等
设定系统、机器人的jog进给、程序、测试运行、自动运转、示教操作盘、遥控装置、通信、外围设备I/O、机器人的动作、急停装置、附加轴、数字I/O、群组I/O、模拟I/O、信号数设定换面、机器人启动请求(RSR)、程序号码...
TTCN-3运行时接口TRI定义了TE与SA和PA之间的交互。其中TRI接口中TE与SA之间的接口称为TRI通信子接口,TE与PA之间的接口称为TRI平台子接口,TCI接口中TE与CD之间的接口称TCI-CD接口。 系统适配器SA负责与IUT的通信...
斯坦福无人车控制博士论文,设计无人车控制器的速度达到160公里/小时!,对从事无人车控制方向研究的工程师和研究人员具有非常大的参考意义!
2.读入网格时,error:File haswrong dimensions(2) 3.the use of axis boundary conditions is not appropriate for 2D/3D flow problem. 4.error:divergence detected in AMG solver 5.error:temperature ...
带精英策略的非支配排序遗传算法,降低了算法的复杂度,扩大了采样空间并提高了解的质量,此代码是c程序代码,附加二进制及约束处理
* Fixed #612: hotkey handing and toReverseFullExpandHotKey * Fixed #602: Dangling WM_Timer and doubled OnChange calls * Fixed #606: High DPI Inheritance of Form. TBaseVirtualTree.ChangeScale() ...
* Fixed #612: hotkey handing and toReverseFullExpandHotKey * Fixed #602: Dangling WM_Timer and doubled OnChange calls * Fixed #606: High DPI Inheritance of Form. TBaseVirtualTree.ChangeScale() ...
实现svn强制写日志和可修改log功能,可以更方便的更规范的使用svn日志功能.
Added a "revert to saved scan" option (lets you undo changes) Added a "forgot scan" option (in case you forgot what you're doing) Pointerscan limit nodes is default on in a new ce install (remembers ...
02.专四阅读真题讲义(2015年-2018年).pdf
软件错误处理 在节点中编写了api,这些Api可以使您集成任何项目,以通过电子邮件以及您的团队和开发人员查看通知错误。 以及为团队负责人提供UI并显示错误,以实现更好,更快的开发。 正在开发中的项目。
optimized for the needs of safely and securely handing wireless push email in an easily deployed environment and scaled for small businesses… We believe BlackBerry Professional Software provides a...