Android 处理运行时更改

  次阅读 来源:互联网(转载协议) 2016-01-19 10:54 我要评论(0)

原文

http://developer.android.com/guide/topics/resources/runtime-changes.html

处理运行时更改

一些设备配置在运行过程中可能会发生改变(例如屏幕横向布局、键盘可用性和语言)。当这样的变化发生时,Android会重新启动这个正在运行的Activity(onDestroy()方法会被调用,然后调用onCreate()方法)。这个重启的动作是为了通过自动往你的应用程序中载入可替代资源,从而使你的应用适应新的配置。

为了正确执行一次重启,你的Activity在整个平凡的生命周期中重新保存它之前的状态是很重要的,Android是通过在销毁你的Activity之前调用onSaveInstanceState()方法来保存关于应用之前状态的数据。然后你就可以在onCreate()方法或者onRestoreInstanceState()方法中重新保存应用的状态了。为了测试你的应用可以通过应用的状态原封不动地重启自己,你应该给你的应用授权当程序在执行不同的任务时应用的配置可以改变(例如屏幕的方向变化)。

为了处理一些事件,例如当用户接听一个打入的电话然后返回到你的应用程序中,在没有丢失用户数据或者状态信息的情况下,你的应用应该具备在任何时候重启自己的能力(更多参见Activity lifecycle)。

然而,你可能要面对这样一个情景,重启你的应用程序并重新保存大量有价值的数据会导致很差的用户体验。在这样的情景面前,你有两种选择:

a.在配置改变期间维持一个对象

当配置发生改变时允许你的Activity重启,但让其携带一个有状态的对象到你的新Activity实例中。

b.你自己来处理配置的变化

当某些配置发生变化的时候阻止系统重启你的Activity,并且当配置改变时要接收一个回调,这样你就可以根据需要来手动更新你的Activity。

在配置改变期间维持一个对象

如果重启你的Activity,你需要恢复大量的数据,重新执行网络连接,或者其他深入的操作,这样由配置改变引起的一次完全启动就会引起不好的用户体验。而且,仅有Activity生命周期中为你保存的的Bundle对象,你是不可能完全维护你的Activity的状态的 不能传递很大的对象(如bitmap对象),并且这些对象里面的数据必须序列化,然后解序列化,这些都需要消耗很多内存从而使配置改变得很慢。在这样的情境下,当你的Activity由于配置发生改变而重启时,你可以通过重新预置一个有状态的对象来减缓你程序的负担。

在运行期间配置改变时维护一个对象:

1.重写 onRetainNonConfigurationInstance() 方法来返回你想要维护的对象。

2.当你的Activity再次创建时,调用getLastNonConfigurationInstance()方法恢复你的对象。

当你的Activity由于配置发生改变要关闭的时候,Android会在执行onStop()方法与onDestroy()方法之间调用onRetainNonConfigurationInstance()方法。为了在配置改变后更有效地保存状态,在实现onRetainNonConfigurationInstance() 方法时你应该返回你所需要的一个对象。

这个场景的可贵之处在于当你的应用程序需要从网上下载很多数据的时候。如果用户更改设备的方向并且Activity重启,你的应用程序必须要重新载入数据,那就会很慢了。你需要做的就是实现onRetainNonConfigurationInstance() 方法并返回带有你的数据的对象,然后当你的Activity通过getLastNonConfigurationInstance()方法重启时就能获取数据。例如:

@Override

public Object onRetainNonConfigurationInstance() {

final MyDataObject data = collectMyLoadedData();

return data;

}

特别提醒:当你要返回任何对象的时候,你应该不要传递一个跟Activity有关联的对象,例如一个Drawable对象,一个Adapter对象,一个View对象或者任何其他跟Context相关的对象 。如果你这样做,它会泄漏原来Activity实例的所有视图和资源。(泄漏资源意味着您的应用程序保持对他们的持有,他们不能被当做垃圾收集,因此内存就泄露了)

然后当你的Activity重启时获取数据:

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance();

if (data == null) {

本站部分文章来源于网络以及网友投稿,本站只负责对文章进行整理、排版、编辑,是出于传递更多信息之目的,并不意味着赞同其观点或证实其内容的真实性。如果您有什么意见或建议,请联系QQ28-1688-302!

人工智能实验室
相关文章相关文章
  • Michael I. Jordan带你解读百万奖金ATEC蚂蚁人工智能大赛

    Michael I. Jordan带你解读百万奖金ATEC蚂蚁人工智能大赛

  • 2018深圳国际人工智能展览会 2018 shenzhen International Artif

    2018深圳国际人工智能展览会 2018 shenzhen International Artif

  • Oculus公布原型机,大幅度提升可视角,能实现140°的视场水平

    Oculus公布原型机,大幅度提升可视角,能实现140°的视场水平

  • teamLab创始人猪子寿之: 抛去衣食住行,我还剩下什么?

    teamLab创始人猪子寿之: 抛去衣食住行,我还剩下什么?

网友点评网友点评
阅读推荐阅读推荐

据外媒报道,STEER打造了首款完全自动驾驶停车技术,旨在使常规车辆转变为无人驾驶车辆。STEER的首款技术应用是4级自动驾驶及网络安全停车...

近日,美国软性机器抓手制造商 Soft Robotics 宣布,获得 2000 万美元的融资,本轮投资者包括 Scale Venture Partners,Calibrate Ventures...

据外媒报道,加州车管局发布了《2017自动驾驶脱离报告(California Autonomous Vehicle Disengagement Reports)》,其中谈及了脱离的具体...

用人机语音交互,来解决智能家居适老的问题;通过家庭门禁与安防套件、空气净化套件、可燃气体与有害气体监控套件等相互联动,在不同生活情...