手动保存和恢复活动的实例状态

时间:2016-06-10 22:07:13

标签: android android-activity persistence

我的应用中有一个下载活动,用户可以在其中下载一些内容。活动从主活动调用,并检索可通过网络下载的可用文件列表。

为了避免在重新创建下载活动时再次获取整个列表,例如由于轮换,我覆盖onSaveInstanceState()以将列表存储在Bundle中,并评估传递给Bundle方法的onCreate()。这适用于轮换。

但是,如果用户点击Back并稍后返回下载活动,我希望能够实现相同的行为。在这种情况下,Android不会调用onSaveInstanceState(),因此不会保存任何内容。

我的想法是覆盖onBackPressed()并包含对onSaveInstanceState()的调用。

  • 这会起作用吗?
  • 我可以执行onSaveInstanceState(new Bundle()),还是必须以某种方式初始化新捆绑包?
  • Android会存储捆绑包并将其传递给onCreate()以获取它创建的活动的下一个实例,或者我是否必须小心存储Bundle并将其传递给新实例(如果是,如何)?

更新

简单地添加

@Override
public void onBackPressed() {
    onSaveInstanceState(new Bundle());
    super.onBackPressed();
}

给了我以下例外:

java.lang.IllegalStateException:onSaveInstanceState之后无法执行此操作

致电onBackPressed()。 (交换这两行没有任何作用,大概是因为没有什么可以保存。)

2 个答案:

答案 0 :(得分:3)

  

这会起作用吗?

没有

  

Android会存储捆绑包并将其传递给onCreate()以获取其创建的活动的下一个实例

没有

  

我是否必须小心存储Bundle并将其传递给新实例(如果是,如何)?

没有

将模型数据存储在文件或数据库中,并使用进程级缓存(例如,自定义单例)来最小化磁盘I / O.将数据从可用的缓存中加载出来,或者根据需要从磁盘重新加载。

答案 1 :(得分:1)

我终于想出了下面描述的解决方案。

关于用法的说法:这将使下载活动的状态保持在主存储器中,它将占用空间。此外,Android可能会在任何时候终止后台应用程序,通常是在内存不足的情况下。如果发生这种情况,状态信息将丢失。

对于我的特定用例,我认为我可以忍受这些限制:我的应用程序编写的状态信息在千字节范围内,如果状态信息丢失,则可以重新创建(只需要时间来获取从服务器列出)。 YMMV。

在下载活动的onStop()方法中,执行:

Bundle outState = new Bundle();
this.onSaveInstanceState(outState);

outState存储在可在需要时检索的位置。就我而言,处理下载管理器事件的BroadcastReceiver是放置它的地方。

要从BroadcastReceiver调出活动,请执行以下操作:

Intent downloadIntent = new Intent(context, DownloadActivity.class);
downloadIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
downloadIntent.putExtra("savedInstanceState", savedInstanceState);
context.startActivity(downloadIntent);

在下载活动的onCreate()方法中,执行:

@Override
protected void onCreate(Bundle savedInstanceState) {
    Bundle state = savedInstanceState;
    if (state == null)
        state = this.getIntent().getBundleExtra(Const.KEY_SAVED_INSTANCE_STATE);
    super.onCreate(state);
}