2012-03-02 3 views
47

В моем приложении есть статическая переменная, которой присваивается значение null, когда я возвращаюсь в свое приложение из внешнего браузера. Похоже, приложение или часть его убиты, если внешняя веб-страница, которую я запускаю, достаточно сложна.статическая переменная null при возврате в приложение

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

Есть ли флаг для предотвращения такого поведения?

+0

«Если приложение должно быть полностью убито, а затем переведено из основного действия, которое было бы нормально ...» - в этом случае просто создайте класс, который расширяет «приложение» и удерживает там статическую переменную. – Squonk

+2

Так есть ли разница в области статичности, если в Application.java или какой-либо другой? – jchristof

+0

@jchristof слишком поздно, но статическое поле приложения не будет иметь значения – oscarthecat

ответ

33

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

Вы должны сохранить свои данные где-то более долговечными. Вы можете найти эту статью по общему Data Storage. Этот вопрос также должен быть уместным: Saving Android Activity state using Save Instance State

Обратите внимание, что это фактически не проблема с одним из шести устройств. Это «проблема» на всех устройствах, это более очевидно на одном из ваших устройств, вероятно, потому, что у него меньше памяти. Если вы запускаете приложение с очень интенсивной памятью на любом из ваших других устройств, вы должны увидеть такое же поведение. Также нет флажка для предотвращения этого. Это стандартное и ожидаемое.

+0

Итак, во всех случаях это утверждение истинно: «Все действия в манифесте приложения должны быть способными запускать приложение для запуска приложения». – jchristof

+0

Нет. Если ваше приложение убито в фоновом режиме в Activity B, а Activity A - это основной запуск в вашем приложении, тогда действие A будет запущено при перезапуске приложения. Вы также можете найти [этот документ] (http://developer.android.com/reference/android/app/Activity.html#ProcessLifecycle) информативный. – kabuko

+0

Я запутался в этом вопросе, потому что все это происходит в этом случае: Activity B запускает собственный браузер. Назад из браузера onCreate() активности B (не onResume()). Статическая переменная имеет значение null, которое было действительным до момента запуска браузера. – jchristof

4

Нет ... вы не должны хранить данные в статических переменных на android. Если вы настаиваете на этом, вам нужно будет оправиться от него, когда оно равно null. Вы должны сохранить свое состояние с помощью пакетов или других средств.

0

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

private static MyObjType getVariable() 
{ 
    if (myVar == null) 
    myVar = new MyObjType(); // do whatever else you need to here 

    return myVar; 
} 

Таким образом, вы можете заменить ваши вызовы на myVar.test() с GetVariable(). test(), и вы знаете, что это никогда не приведет к исключению нулевого указателя.

+1

У этого есть условия гонки –

4

Решения с использованием статики (Синглтона) в Android очень просто:

Реализовать класс, который расширяет android.app.Application и сделать всю вашу одноплодную инициализацию в onCreate()

Рассуждения:

  • класс что расширение приложения выполняется сначала, даже когда процесс вашего приложения убит из-за низкого состояния памяти
  • ваше приложение имеет контекст, как только a s Application.onCreate() называется
+1

класс, который расширяет Приложение, * выполнен * сначала ?? Что означает выполнение? Более того - можете ли вы предоставить документы для этого требования? –

+0

также добавить их в манифест, как Qamar

0

Используйте класс приложения для таких вещей. Он всегда создается, прежде чем какой-либо компонент (действия, службы, приемники) вашего приложения начнутся. Таким образом, вы уверены, что все статические переменные есть и инициализированы.

1

Вы должны сохранить свои значения в onSaveInstanceState и вернуть их в onRestoreInstanceState, потому что когда действие переходит к остановленному жизненному циклу состояния, все статические значения будут равны нулю.

например:

 /* save my satatic hashmap in case of activity stopped to retrieve it again in onRestoreInstanceState method*/ 
     @Override 
     protected void onSaveInstanceState(Bundle outState) { 
      super.onSaveInstanceState(outState); 

    //Common.PERMISION_MAP static hashmap 
      if (Common.PERMISION_MAP != null) { 
       Iterator<Permission> iterator = Common.PERMISION_MAP.values() 
         .iterator(); 
       ArrayList<Permission> permissionList = new ArrayList<Permission>(); 
       while (iterator.hasNext()) { 
        Permission permission = (Permission) iterator.next(); 
        permissionList.add(permission); 

       } 
       outState.putParcelableArrayList("PERMISSION_LIST", permissionList); 
      } 


     } 

     /* restore my satatic hashmap when activity stopped */ 
     @Override 
     protected void onRestoreInstanceState(Bundle savedInstanceState) { 
      super.onRestoreInstanceState(savedInstanceState); 

      try { 
       ArrayList<Permission> permissionList = savedInstanceState 
         .getParcelableArrayList("PERMISSION_LIST"); 

       if (Common.PERMISION_MAP == null) 
        Common.PERMISION_MAP = new HashMap<Permission, Permission>(); 
for (Permission permission : permissionList) { 
       Common.PERMISION_MAP.put(permission, permission); 

      } 
       } catch (Exception ex) { 
       String string = ex != null ? ex.getMessage() : ""; 
       Log.e(TAG, (string != null ? string : "")); 
       ex.printStackTrace(); 

      } 
     } 
17

Обычно это происходит, когда устройство переходит в режим ожидания .

Такое поведение устройства можно эмулировать с помощью следующих шагов:

  1. Запустите приложение и нажмите кнопку Home
  2. В Android Studio в нижнем левом углу, выберите отлажена приложение и нажмите кнопку X (прекратите приложение) слева от имени приложения. (Не знаю, как Eclipse, но я думаю так же)
  3. Нажмите на значок приложения на устройстве.

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

+1

Это полезно для воспроизведения шагов. Теперь отлаженное приложение классифицируется на вкладке ** Android Monitor **. –

+0

Как насчет нестатических переменных? –

Смежные вопросы