集册 Android&Java 技术笔记 处理App运行时配置的变化(屏幕方向,语言等)

处理App运行时配置的变化(屏幕方向,语言等)

—— Handling Runtime Changes

欢马劈雪     最近更新时间:2020-08-04 05:37:59

107

Runtime Changes包括orientation,键盘可见性,语言设置等,这些内容发生变化后, 系统将重启Activity(先执行onDestroy,再执行onCreate),以便APP可以响应 这些变化。

onSaveInstanceState()onRestoreInstanceState()回调在这种情形下可以 使得APP能保存已有状态,在Activity重新创建时能够恢复已有状态,为用户提供一致的体验。

如果需要把已加载的数据应用到新的状态中,有两种方式:

  • 在配置发生变化时,保留数据
  • 当配置发生变化时,不要重新创建Activity(系统默认行为),而是响应相应事件, 手动改变Activity状态

Retaining an Object During a Configuration Change

onSaveInstanceState()onRestoreInstanceState()并不是设计用来传递大量数据的, 其传递的Bundle对象有大小限制。而且Bundle中的数据都会先反序列化再序列化,耗时较多。

可以使用Fragment,调用Fragment::setRetainInstance(true),在Activity重新创建之后, 通过FragmentManager获取到重用的Fragment对象,进而获取到已有的数据。这里需要注意的是, Fragment不能直接或者间接持有Activity的引用,否则可能会导致老的Activity对象的内存泄漏。

利用这一方式,有一种HeadlessFragment的用法,这个Fragment没有UI,只负责后台加载数据, 它不会因为Activity的配置变化销毁而销毁,可以保证数据获取过程的连续性。

Handling the Configuration Change Yourself

Activity可以在manifest中声明自行处理配置变化,同时onConfigurationChanged()回调会 在配置变化时被执行。这种方式是最为复杂的,应该是最后的考虑选项。

android:configChanges="orientation|screenSize|keyboardHidden"

配置发生变化之后,getResources()函数返回的对象是新配置下的资源对象,可以直接使用,

Loaders

相比于上述通过Fragment保留数据的方式,更建议使用Loaders进行替换。Loaders自安卓3.0引入, 用于异步加载数据,Activity和Fragment均可以使用。

Loader框架包含了一个CursorLoader实现,包括了异步请求数据,Activity/Fragment销毁重新 创建时直接返回已有数据等功能。

展开阅读全文