何时/为什么我的 Java 单例实例被销毁?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7503997/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 20:16:37  来源:igfitidea点击:

When/why does my Java singleton instance get destroyed?

javaandroidsingletonandroid-ndk

提问by lost_bits1110

I have an android app that is setup to start a Java activity (call it MyJavaActivity), which in turn launches a NativeActivity. When the NativeActivity finishes it returns back to MyJavaActivity.

我有一个 android 应用程序,它被设置为启动一个 Java 活动(称为 MyJavaActivity),它依次启动一个 NativeActivity。当 NativeActivity 完成时,它返回到 MyJavaActivity。

I also have a Java singleton class (call it MyJavaSingleton) which I would like to stay in memory throughout my application's lifecycle. I set some of the singleton class's member variables from my NativeActivity (using JNI), which can later be retrieved by MyJavaActivity.

我还有一个 Java 单例类(称为 MyJavaSingleton),我希望它在我的应用程序的整个生命周期中都保留在内存中。我从我的 NativeActivity(使用 JNI)设置了一些单例类的成员变量,稍后可以由 MyJavaActivity 检索。

The problem is, MyJavaSingleton instance seems to be in memory until NativeActive exits, but somehow seems to be set to null again when MyJavaActivity starts up again, so all the variables I had set in NativeActivity are now reset to their defaults. Why does this happen?

问题是,MyJavaSingleton 实例似乎在内存中,直到 NativeActive 退出,但不知何故,当 MyJavaActivity 再次启动时,似乎又设置为 null,所以我在 NativeActivity 中设置的所有变量现在都重置为默认值。为什么会发生这种情况?

 public class MyJavaActivity extends Activity implements View.OnTouchListener
 {
   @Override
   public void onCreate(Bundle savedInstanceState) 
   {
    super.onCreate(savedInstanceState);
    MyJavaSingleton.Instance().DoStuff();
   }

   @Override
   public boolean onTouch(View arg0, MotionEvent arg1) 
   {
      Intent intent = new Intent(MyJavaActivity.this, NativeActivity.class);
      startActivity(intent); // at this point, android_main will be executed 
   }
 }

 /////////////////////////////
 public class MyJavaSingleton
 {
   static private MyJavaSingleton mInstance = null;
    synchronized public static MyJavaSingleton Instance()
{
    if( mInstance == null )
    {
        mInstance = new MyJavaSingleton();
        Log.v(TAG, "New MyJavaSIngleton instance");
    }
    return mInstance;
}
 }
 /////////////////////////////
 // Native 
 void android_main(struct android_app* state) 
 {
     // Do various stuff, set some variables on the MyJavaSingleton
     // At this point, MyJavaSingleton.mInstance is still at the same address in memory, which is good //
     ANativeActivity_finish(state->activity);
     exit(0);
     // Problem: sometime after this exit and before MyJavaActivity::onCreate is called, MyJavaSingleton.mInstance is set to null! 
 }

In the above code extraction, "New MyJavaSIngleton instance" is printed when the app is first started, and then again right after the NativeActivity exits (ie after android_main is exited) and MyJavaActivity's onCreate is called again.

在上面的代码提取中,“New MyJavaSIngleton instance”在应用程序第一次启动时打印,然后在 NativeActivity 退出后(即退出 android_main 后)再次打印,并再次调用 MyJavaActivity 的 onCreate。

Why does MyJavaSingleton.mInstance become NULL when reentering MyJavaActivity?

为什么在重新进入 MyJavaActivity 时 MyJavaSingleton.mInstance 变为 NULL?

回答by RHT

Each Android app runs in its own process so as long as it keeps running, your singleton will be available. When the process dies, your singleton is lost. Therefore when the app is re-launched this singleton object will need to be re-created.

每个 Android 应用程序都在自己的进程中运行,因此只要它继续运行,您的单例就可用。当进程终止时,您的单身人士就会丢失。因此,当应用程序重新启动时,需要重新创建这个单例对象。

回答by hackbod

Be sure to read the documentation on the process lifecycle:

请务必阅读有关流程生命周期的文档:

http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html#Lifecycle

http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html#Lifecycle

In this case, whenever your app is in the background (in terms of activities, none of your activities are visible to the user), your process can be killed at any time. If the user later returns to one of your activities, a new process will be created and a new instance of the activity created.

在这种情况下,只要您的应用程序处于后台(就活动而言,您的任何活动都对用户不可见),您的进程就可以随时终止。如果用户稍后返回到您的活动之一,则将创建一个新流程并创建该活动的新实例。

回答by James DW

I'd make mInstance private. Just in case some other code is accidentally setting it.

我会将 mInstance 设为私有。以防万一其他代码不小心设置了它。

回答by bmaupin

"Android OS can and will terminate your singleton and not even tell you about it."

“Android 操作系统可以并且将会终止你的单身人士,甚至不会告诉你这件事。”

Source: http://www.2linessoftware.com/2010/08/03/singletons-and-services-and-shutdowns-oh-my/

来源:http: //www.2linessoftware.com/2010/08/03/singletons-and-services-and-shutdowns-oh-my/

The author of that article suggests some solutions, such as using a Service, or subclassing the Application class. There seems to be quite a bit of support for the latter:

那篇文章的作者提出了一些解决方案,例如使用 Service,或子类化 Application 类。似乎有相当多的人支持后者:

How to declare global variables in Android?

如何在Android中声明全局变量?