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

Android 一个应用程序中活动的并发实例?,android,android-activity,activity-lifecycle,Android,Android Activity,Activity Lifecycle,我有一个Android应用程序,只有一个活动(MainActivity)。我还有一个静态变量(foo),它需要通过MainActivity启动和停止。foo的生存期必须与MainActivity的整个生存期相匹配,而不是它的可见生存期,也不是它的前景生存期。以下是基本要点: static Foo foo; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); f

我有一个Android应用程序,只有一个活动(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


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

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

从活动文档中:

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

因此,您应该在onStart/onStop或onResume/onPause中调用foo.start/foo.stop

--

更新:

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

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

因此,解决方案是使用实例计数器:

public class Foo {
private int instCounter = 0;

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

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

这应该可以解决问题。

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


您应该将数据保存在更耐用的地方。您可能会发现这篇关于general的文章很有用。这个问题也应该相关:

Foo的确切定义在哪里?

它是否扩展了Android API中的某些内容?您能发布该异常的完整堆栈跟踪吗?不幸的是,我在m中有两个不同的“Foo”我的主要活动远不像上面那么简单。我的Foos中最令人沮丧的是SQLiteOpenHelper的一个子类,我的“Foo已经在运行时启动”是一个非法状态异常:尝试重新打开一个已经关闭的数据库。我看到了,但仍然不足以帮助您。发布完整的stacktrace。我理解d您的沮丧,但这一个没有真正的stacktrace,因为没有真正的代码。在这个玩具示例中,stacktrace是foo.start()由MainActivity.onCreate()调用。我正在寻找一种不同的方法来构造第三方库的初始化和实例化/与数据存储的交互,以避免将来的维护。也许我需要以某种方式将我的问题分开…我想了解为什么我的活动会在同一个应用程序中重新实例化,我想打赌放我启动代码的地方。IllegalStateException是一个异常,应该有stacktrace。BFrustration?不,你错了。你是寻求帮助的人,不是我。我只是想帮助,但你不让我。请允许我:)我从许多不同的渠道听到过这个,但我从未亲身经历过,我也不完全理解“静态变量在返回时可能为空”的含义。我相信您的意思是,托管活动的整个进程及其整个内存空间可能随时被擦除。返回到“活动”时,不能依赖“活动”下的任务堆栈中已经运行或存在的任何其他活动。如果这就是你的意思,那么我完全同意,但我认为这并不能回答我的问题。我的一个“Foo”是一个数据库,它应该在用户每次启动MainActivity时删除,但在用户“返回”MainActivity时不应删除。也就是说,如果他隐藏了应用程序或导航离开,然后返回应用程序,他的数据将保留。但如果他用后退按钮退出应用程序,他的数据将保持不变。我正在寻找一个合适的模式,以一种通用的方式来实现这一点。这一次我在过去有好几次这样做,所以我把它投了更高的票。但我正在处理配置更改,以防止重新实例化活动。如果我没记错的话,onPause isFinishing()检查也会捕捉到这些。另外,我需要静态变量生存期与活动的整个生存期相关联,而不是与它在可见或前景中的时间相关联。我不确定是否正确理解您的需要,您可以从应用程序类派生的类实例化变量:。关于您的第一条注释:活动类文档中描述了OnStart/onStop和onResume/onPause之间的区别。弹出窗口(如警报对话框)将在暂停时触发,但不会在顶部触发。选择取决于傅做什么。好吧,对不起,我误解了你的第二个建议。有关该职位的详情