2015-04-06 1 views
6

благодаря этому ответу Android Fragment lifecycle issue (NullPointerException on onActivityResult) Мне удалось создать сценарий, когда я получаю NPE в своем фрагменте после вызова startActivityForResult. Так у меня естьAndroid Fragment уничтожается, но получает onActivityResult

Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); 
photoPickerIntent.setType("image/*"); 
startActivityForResult(photoPickerIntent, PHOTO_SELECT_REQUEST_CODE); 
break; 

вызывается из моего фрагмента, то моя деятельность получает OnPause, OnStop и OnDestroy, поэтому фрагмент, который называется startActivityForResult получает OnDestroy, а также. После того, как я выбираю изображение, я получаю новый onCreate в своей деятельности, а затем получаю public void onActivityResult на моем исходном фрагменте, который теперь уничтожен.

Мой вопрос в том, что это потенциально (хотя и редкая) ситуация, как бы восстановить весь стек фрагментов и объектов, переданных им, и что он делает, чтобы предотвратить утечку исходного фрагмента?

+0

Вы уверены, что onActivityResult доставляется к старому фрагменту? Пробовали ли вы регистрировать объект фрагмента (this) в onCreate/onCreateView и onActivityResult? Это даст вам четкое представление о том, какой фрагмент вызывается onActivityResult. –

ответ

0

Когда ваш код выполняет следующую строку:

startActivityForResult(photoPickerIntent, PHOTO_SELECT_REQUEST_CODE); 

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

Для сохранения состояния фрагмента и активности и предотвращения утечки:

Сохранить состояние в onSaveInstanceState(Bundle)

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

Восстановление состояния в onRestoreInstanceState(Bundle)

onRestoreInstanceState(Bundle) метод вызывается после onStart(), когда активность повторно инициализируется из ранее сохраненного состояния, приведенного здесь в savedInstanceState. Большинство реализаций просто используют onCreate(Bundle) для восстановления своего состояния, но иногда это удобно делать здесь после завершения инициализации или разрешать подклассам решать, следует ли использовать реализацию по умолчанию. По умолчанию реализация этого метода выполняет восстановление любого состояния представления, которое ранее было заморожено на onSaveInstanceState(Bundle).

Это может помочь вам реализовать ваши требования

+0

Благодарим вас за ответ. Я реализовал логику воссоздания активности и фрагментов на основе onSaveInstanceState/onRestoreInstanceState. Тем не менее, я все же сталкиваюсь с проблемой «оставшегося» фрагмента. Поскольку он зарегистрирован для получения результата активности, он не будет помечен для GC, и я не могу придумать хороший способ перенаправить этот результат на фрагменты, которые были заново созданы. –

+0

@DmitryGolomidov Вы нашли ответ? Я столкнулся с той же проблемой. – kong