如何在android中清理全局状态

时间:2013-04-19 08:26:58

标签: java android

我正在开发一个Android应用程序,它有一些全局状态(包括几个SoundPool,需要一段时间才能加载)而且我正在寻找管理它的最佳方法。到目前为止,我可以看到两个选项,这两个选项都不完美:

  1. 将状态存储在我的主Activity中 - 这很好地挂钩到Activity生命周期(有机会清理),并且屏幕轮换我可以使用onRetainNonConfigurationInstance和{ {1}}保留状态,但是当在活动之间导航时,此状态将完全丢失并且必须重新加载,这将是无法接受的缓慢

  2. 将状态存储在全局单例或getLastNonConfigurationInstance子类中 - 这允许状态在活动之间保持导航,但因为Application没有Application事件,所以没有有机会发布onDestroy

  3. 有关更好方法的建议吗?或者,当应用程序被停止/杀死时,我是否应该担心释放SoundPools?

    谢谢,克里斯

2 个答案:

答案 0 :(得分:2)

两者不仅不完美,而且实际上是非常糟糕的架构。

Singleton模式总体上受到越来越多的批评,而对于Android来说更糟糕的是因为你不能保证你的Application对象会持久存在(当资源很少时系统会杀掉它,这不是bug但是正确的行为)。

onRetainNonConfigurationInstance自API级别13以来被弃用,并且被Android团队本身描述为“脏黑客”;这不是你想要使用的。

您可以通过在独立于您的活动的服务中托管Soundpool持久性问题来解决它。一旦不需要再玩,就一定要杀掉服务。

答案 1 :(得分:0)

好的,这不是一个完整的答案,但我会跟进一个更具体的问题。

但原则上,拥有本地Service确实如下:

  • 拥有持有州的本地“绑定”服务
  • 有各种活动,每个活动都绑定并解除绑定,例如:

@Override
public void onStart() {
    super.onStart();
    Intent intent = new Intent(this, LocalStateService.class);
    bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
}

@Override
public void onStop() {
    if (stateService != null) {
        unbindService(serviceConnection);
        stateService = null;
    }
}

@Override public void onStart() { super.onStart(); Intent intent = new Intent(this, LocalStateService.class); bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); } @Override public void onStop() { if (stateService != null) { unbindService(serviceConnection); stateService = null; } }

由于活动生命周期故意重叠,因此服务将一直存在,直到用户退出应用程序(或者只是离开它并开始执行其他操作)。此时,在服务上调用然后onUnbind

太好了,我们快到了。但是,该服务无法在配置重启(例如屏幕旋转)后继续存在,因此我将其作为单独的问题发布...