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

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

 

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

 

 

 

 

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

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

 

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

 

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

 

@Override
public 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等。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值