一个应用程序中的并发活动实例?

时间:2015-05-06 15:22:45

标签: android android-activity activity-lifecycle

我有一个Android应用程序,只有一个Activity(MainActivity)。我还有一个静态状态变量(foo)需要使用MainActivity启动和停止。 foo的生命周期必须与MainActivity的整个生命周期相匹配,而不是其可见生命周期,也不符合其前景生命周期。这是基本要点:

static Foo foo;

public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    foo.start();
}

protected void onPause()     
{
    super.onPause();
    if (isFinishing())
        disposeFoo();
}

protected void onDestroy()
{
    super.onDestroy();
    disposeFoo();
}

private void disposeFoo()
{
    if (foo.isRunning())
        foo.stop();
}

每次我都会得到一份崩溃报告:Foo已经开始运行了。

我可以从应用启动器整天开始和停止MainActivity,并且不会发生此崩溃。据我所知,没有人在MainActivity上调用startActivity。

在同一个应用程序中的旧实例上运行onDestroy之前,是否会创建一个新的MainActivity实例,并且onCreate会调用它?在什么情况下会发生这种情况?我应该使用不同的模式来初始化库,数据库和其他单例对象吗?

2 个答案:

答案 0 :(得分:1)

例如,如果因屏幕旋转而重新创建活动,则不会调用onDestroy

来自活动文档:

  

在您的活动被销毁之前收到的最后一个电话。这可能是因为活动正在完成(有人在其上调用finish(),或者因为系统暂时销毁此活动实例以节省空间。您可以使用isFinishing()方法区分这两种情况。

所以你应该在onStart / onStop或onResume / onPause上调用foo.start / foo.stop。

-

更新:

如果我理解正确,问题是你被绑定到单个/单一对象Foo应该对所有对象都是唯一的,并且必须在销毁所有活动时销毁它。

问题在于没有任何东西可以保证只有一个活动实例具有runinng Foo,因为在创建新实例之后可以调用onDestroy

所以解决方案是使用实例计数器:

public class Foo {
private int instCounter = 0;

public synchronized void start() {
    ...
    ++instCounter;
}

public synchronized void dispose() {
    --instCounter;
    if (instCounter == 0) {
         // dispose
    }
}

这应该可以解决问题。

答案 1 :(得分:1)

如果某个其他具有较高优先级的应用程序(通常情况下,如果它位于前台,它的优先级较高)需要资源,那么您的应用 经常会被杀死。这是由于具有相对有限资源的移动设备的性质。一旦你返回它,它会发现它的静态变量可能为null,因此Android中较长时间的静态变量是一个坏主意。

您应该将数据保存在更耐用的地方。您可能会发现这篇关于通用Data Storage的文章很有用。这个问题也应该是相关的:Saving Android Activity state using Save Instance State