我的应用中有一个下载活动,用户可以在其中下载一些内容。活动从主活动调用,并检索可通过网络下载的可用文件列表。
为了避免在重新创建下载活动时再次获取整个列表,例如由于轮换,我覆盖onSaveInstanceState()
以将列表存储在Bundle
中,并评估传递给Bundle
方法的onCreate()
。这适用于轮换。
但是,如果用户点击Back并稍后返回下载活动,我希望能够实现相同的行为。在这种情况下,Android不会调用onSaveInstanceState()
,因此不会保存任何内容。
我的想法是覆盖onBackPressed()
并包含对onSaveInstanceState()
的调用。
onSaveInstanceState(new Bundle())
,还是必须以某种方式初始化新捆绑包?onCreate()
以获取它创建的活动的下一个实例,或者我是否必须小心存储Bundle
并将其传递给新实例(如果是,如何)?更新
简单地添加
@Override
public void onBackPressed() {
onSaveInstanceState(new Bundle());
super.onBackPressed();
}
给了我以下例外:
java.lang.IllegalStateException:onSaveInstanceState之后无法执行此操作
致电onBackPressed()
。 (交换这两行没有任何作用,大概是因为没有什么可以保存。)
答案 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);
}