2016-09-29 3 views
-1

Я не понимаю, как работают андроиды.Активность в Android-качестве случайно Создана и уничтожена

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

НЕ ТАК!

Кажется, что когда мое приложение возобновляется, Activity3 воссоздан и OnCreate вызывается с теми же параметрами, как это было в первый раз (когда он был вызван из деятельности2) только на этот раз все синглтоны и другие объекты, которые были инициализированы в Activity1 и Activity2 воссозданы с их значениями по умолчанию и оказываются бесполезными.

Как это безопасная политика/техника? Как андроид может случайно уничтожить объекты и действия, а затем, когда пользователь возобновит, просто вызовите onCreate в недавнем действии и ожидайте, что все будет тяжелым, а НЕ нужно пройти надлежащую процедуру запуска/инициализацию?

UPDATE/РЕШЕНИЕ

Благодаря к commentors за отличную информацию.

СОГЛАСНО ANDROID ДОКУМЕНТАЦИИ

OnCreate

Bundle: Если активность повторной инициализации после того, как ранее закрываются, этот Bundle содержит данные, которые он совсем недавно поставляемые в onSaveInstanceState (Bundle). Примечание: В противном случае оно равно null.

ПОЭТОМУ, что я в конечном итоге делает это я поставил два флага. Один в onSaveInstanceState в комплекте, чтобы знать, что это действительный комплект, установленный мною. Другой в своем классе, чтобы определить, был ли onCreate вызван из-за отдыха или Автоматическое вращение. И так в onCreate Я проверил, если onSaveInstanceState не имеет значения null, проверьте флаг Bundle и отметьте bInit (по умолчанию это значение false). Если оба флага верны, это означает, что андроид сбрасывал и уничтожал нашу память приложений, а самый безопасный способ убедиться, что все снова инициализировано в приложении с линейным стилем, - это просто перезапустить его и запустить начальную активность.

public class SomeMiddleActivity extends AppCompatActivity 
{ 
    private static boolean bInit = false; // only way it will be false again is if android cleared our memory and we are recreating 

    @Override 
    public void onSaveInstanceState(Bundle state) 
    { 
     // set a flag so that onCreate knows this is valid 
     state.putBoolean("StateSaved", true); 
     super.onSaveInstanceState(state); 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     // this must be called first always for some reason 
     super.onCreate(savedInstanceState); 

     if (savedInstanceState != null) 
     { 
      if (savedInstanceState.getBoolean("StateSaved", false) && !bInit) 
      { 
       // we were recreated... start app over 
       Intent intent = new Intent(getApplicationContext(), Startup.class); 
       startActivity(intent); 
       finish(); 
       return; 
      } 
     } 

     bInit = true; // this will stay true until android has cleared our memory 

     ....... 
    } 

Хотя это сработало до сих пор, если у кого есть другое предложение, дайте мне знать. Я опубликую еще одну статью об этом.

И FYI:onSaveInstanceState (Bundle, PersistableBundle) версия onSaveInstanceState никогда не называли когда-либо, так что я не знаю, почему они даже реализовать. (?)

@goldenb @Rishabh Благодаря goldenb и Rishabh для проницательности.

+0

Пожалуйста, удалите 'SOLVED' из вашего названия и опубликовать решение, которое вы нашли в качестве надлежащего ответ (то есть, если это не совсем то же самое, что и один из ответов). – usr2564301

+0

почта, где? .... – zdanman

+0

В большой пустой коробке с надписью «Ваш ответ», ниже данных решений. – usr2564301

ответ

1

Android, если он уничтожает, также предоставляет инструменты для его обработки.

Мобильные устройства имеют ограниченный объем памяти, который должен использоваться совместно между приложениями, запущенными одновременно. Таким образом, требуется выделение интеллектуальных ресурсов. Приложения, работающие на переднем плане, используются конечным пользователем и получают высокий приоритет для повышения производительности и удобства работы. Таким образом, приложения, работающие в фоновом режиме, должны выделять ресурсы, достаточные для требований к памяти для приложений переднего плана. Следовательно, фоновые приложения иногда уничтожаются (не полностью) (в случае низкой памяти).

Android Мероприятие имеет Callbacks любит onSaveInstanceState() и onRestoreInstanceState(), которые позволяют сохранить текущее состояние активности (то есть значения переменных), когда она разрушается и извлекать их, когда активность воссоздана.

Вы можете получить более подробную информацию здесь: How to save and retrieve the state of Activity using onSaveInstanceState and onRestoreInstanceState.

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

+0

есть ли способ, чтобы приложение полностью перезапустилось при возобновлении экземпляра? – zdanman

+1

Возможны обходные пути (например, чтобы убить процесс и перезапустить его), но они не рекомендуются. Скорее, вы можете очистить стек задачи активности (используя флаги Intent) и запустить Launcher Activity (может быть, уведомлять пользователя, если требуется). –

+0

Позвольте мне запустить это вами. Что делать, если я вызываю ** System.exit (0) ** или ** finish() ** в ** onSaveInstanceState ** ??? Из моего понимания ** onSaveInstanceState ** вызывается и _only_ вызывается, когда приложение находится в фоновом режиме и, вероятно, очищается от памяти. Это заставит приложение запускаться всякий раз, когда пользователь снова нажимает значок приложения. – zdanman

1

Просто дайте 50 центов на эту проблему. Правильный способ иметь дело с вопросом о деятельности был убит системой для своих ресурсов в фоновом режиме является общей проблемой в андроиде и в соответствии с Google решением для этого является:

OnPause() является, где вы имеете дело когда пользователь покидает вашу деятельность. Большинство важно, чтобы любые изменения, сделанные пользователем, должны в этот момент быть совершенным (обычно для ContentProvider, содержащего данные).

Акцент - мой. Но это означает, что жизненные циклы Android сконструированы так, что в нормальных условиях onPause следует вызывать как активность или фрагмент, который отправляется на задний план. Они намекают на это на нескольких страницах документации по Android:

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

Также достойны вашего внимания: если вы хотите, что мнения будут восстановлены в течение Activity recreation, вы должны установить ID атрибут всех видов;)

Примечание: Для того, чтобы Android системы для восстановления состояние представлений в вашей деятельности, каждое представление должно иметь уникальный идентификатор, предоставленный атрибутом android: id.

PS. Вы задавались вопросом, почему onSaveInstanceState (Bundle, PersistableBundle) не называется, одна возможность заключается в том, что вы не имеете права атрибут деятельности устанавливается

Это то же самое, как onRestoreInstanceState (Bundle), но вызывается для мероприятия, созданные с помощью атрибута persistableMode набора для persistAcrossReboots ..

+1

, кстати, вы также должны испытывать некоторые из этих проблем при повороте устройства. Вы обязательно должны придерживаться своих данных во время onPause() ;) – HenriqueMS

+0

Спасибо, что принесли это. Я забыл, что ** onRestoreInstanceState ** был вызван во время вращения. То, что я сделал, это добавить флаг ** bInit ** в память, который по умолчанию является ложным. Это скажет мне, был вызван onCreate из-за поворота или отдыха. Я обновил статью выше. – zdanman

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

  • Нет связанных вопросов^_^