读书人

Android Configuration 变换时怎么保持

发布时间: 2012-09-28 00:03:35 作者: rapoo

Android Configuration 变换时如何保持珍贵数据不被摧毁

以下文字来源于andoid SDK上一篇文章的大概翻译:

?

当你的应用里显示了一堆数据,这些数据又是开销较大获取的, 在configuration变换如键盘弹出隐藏,横竖屏切换,语言变换等出现时,系统自动的Activity destroy/creation 机制可能会导致非常不好的用户体验。 比如如下的例子,一个简单的Fclikr浏览应用,其从网上下载你账户里的图片。

?

Android Configuration 变换时怎么保持珍贵数据不被摧毁

?

Android Configuration 变换时怎么保持珍贵数据不被摧毁

?

?

如上述横竖屏切换时,如果不做特殊处理,android会自动处理 configuration变换事件,但是, 这样的话应用如果重新下载要显示的图片,用户体验该是多么糟糕。 明显的解决这个问题的办法是cache一下这些图片。 可以cahce这些图片到 SD card里(如果有的话), 或在应用程序的数据对象里, 或在静态数据里等等。 不过前述这些方法都不太适合于这个问题:

为什么我们要有开销来cache这些图片当屏幕没有横竖屏切换?

?

幸运的是,Android提供了一个极好的API, 用来处理这个问题。

?

Activity 类有一个特别的方法,叫 onRetainNonConfigurationInstance(). 该方法可以用来传递一个任意的对象, 你的应用可以在将来需要时调用此方法。 在上面的应用里,可以将下载的图片通过此接口传递。实现类似如下:

?

@Overridepublic Object onRetainNonConfigurationInstance() {    final LoadedPhoto[] list = new LoadedPhoto[numberOfPhotos];    keepPhotos(list);    return list;}

?

在横竖切换后,新创建的Activity里的onCreate函数,你要做的是是将你的对象取回来,通过getLastNonConfigurationInstance() 接口。

?

private void loadPhotos() {    final Object data = getLastNonConfigurationInstance();        // The activity is starting for the first time, load the photos from Flickr    if (data == null) {        mTask = new GetPhotoListTask().execute(mCurrentPage);    } else {        // The activity was destroyed/created automatically, populate the grid        // of photos with the images loaded by the previous activity        final LoadedPhoto[] photos = (LoadedPhoto[]) data;        for (LoadedPhoto photo : photos) {            addPhoto(photo);        }    }}

?

要注意的是, 传递给onRetainNonConfigurationChange()的对象,不能是跟Activity/Context有关联的, 否则将会有内存泄露所有跟Activity相关联的view和resource。 也即意味着,你不能传递如View, Drawable, Adapter 等等对象。上述应用传递的是图片bitmap本身,而不是drawable.? 最后,还是注意的是,你应该仅用该接口传递较“珍贵”的数据(重新获取代价较大)。

?

?

另外,SDK中还有说明如下:

?

该 接口仅供优化调用,你不能仅仅依靠此接口。 当其被调用时,有一系列保证措施会用来帮助优化configuration切换:

1) 接口将在onStop()和onDestroy()之间调用。

2) 一个新的Activity的实例一般会立即生成,在当前Activity的onDestory()被调用后。 特别是,在这段时间没有消息会被分发(返回的对象没有关联于一个activity).

3) 返回的对象一般将在接下来系统自动重新的Activity实例里通过getLastNonConfigurationInstance()接口获得。

?

这些保证设计用来使一个activity可以将扩展的状态从旧的activity传递到新的activity实例,包括加载的图片,网络连接对象,甚至是正在运行的线程对象。 注意不要传递任何将根据configuration变换的对象,如 对resource里读取的string, layout, drawable等。



读书人网 >Android

热点推荐