Когда / почему мой экземпляр Java синглтона уничтожается?

У меня есть приложение для Android, которое настроено для запуска действия Java (назовите его MyJavaActivity), которое, в свою очередь, запускает NativeActivity. Когда NativeActivity завершается, он возвращается к MyJavaActivity.

У меня также есть одноэлементный класс Java (назовите его MyJavaSingleton), который я бы хотел сохранить в памяти на протяжении всего жизненного цикла моего приложения. Я установил некоторые переменные-члены класса синглтона из моей NativeActivity (используя JNI), которые впоследствии могут быть получены MyJavaActivity.

Проблема в том, что экземпляр MyJavaSingleton, по-видимому, находится в памяти, пока NativeActive не завершит работу, но каким-то образом он снова устанавливается равным нулю, когда MyJavaActivity запускается снова, поэтому все переменные, которые я установил в 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! 
 }

В приведенном выше извлечении кода "Новый экземпляр MyJavaSIngleton" печатается при первом запуске приложения, а затем снова сразу после выхода из NativeActivity (т.е. после выхода из android_main) и повторного вызова onCreate для MyJavaActivity.

Почему MyJavaSingleton.mInstance становится NULL при повторном входе в MyJavaActivity?

4 ответа

Решение

Каждое Android-приложение работает в своем собственном процессе, поэтому, пока оно работает, ваш синглтон будет доступен. Когда процесс умирает, ваш синглтон теряется. Поэтому, когда приложение перезапускается, этот одноэлементный объект необходимо будет заново создать.

"ОС Android может уничтожить ваш синглтон и даже не сказать вам об этом".

Источник: http://web.archive.org/web/20130403145750/http://www.2linessoftware.com/2010/08/03/singletons-and-services-and-shutdowns-oh-my/

Автор этой статьи предлагает некоторые решения, такие как использование Сервиса или создание подкласса класса Application. Похоже, что есть немало поддержки для последнего:

Как объявить глобальные переменные в Android?

Обязательно прочтите документацию по жизненному циклу процесса:

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

В этом случае, когда ваше приложение находится в фоновом режиме (с точки зрения действий, ни одно из ваших действий не видно пользователю), ваш процесс может быть в любой момент завершен. Если впоследствии пользователь вернется к одному из ваших действий, будет создан новый процесс и создан новый экземпляр действия.

Я бы сделал частный случай. На случай, если какой-то другой код случайно установит его.

Другие вопросы по тегам