Когда / почему мой экземпляр Java синглтона уничтожается? - PullRequest
9 голосов
/ 21 сентября 2011

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

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

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

10 голосов
/ 21 сентября 2011

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

2 голосов
/ 21 сентября 2011

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

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

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

1 голос
/ 21 сентября 2011

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

0 голосов
/ 30 сентября 2011

«Операционная система Android может отключить ваш синглтон и даже не сообщать вам об этом».

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...