简体   繁体   中英

When/why does my Java singleton instance get destroyed?

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.

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.

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?

 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.

Why does MyJavaSingleton.mInstance become NULL when reentering MyJavaActivity?

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.

Be sure to read the documentation on the process 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.

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

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

Source: 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:

How to declare global variables in Android?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM