Android Fragment being destroyed yet receiving onActivityResult
Asked Answered
H

1

6

thanks to this answer Android Fragment lifecycle issue (NullPointerException on onActivityResult) I've managed to re-create a scenario when I receive a NPE in my fragment after calling startActivityForResult. So i have

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

being called from my fragment, then my activity receives onPause, onStop and onDestroy, so the fragment that called startActivityForResult gets an onDestroy as well. After I pick an image, i get a new onCreate on my activity and then i get a public void onActivityResult on my original fragment that is now destroyed.

My question is since this is potentially (albeit a rare) situation, how would one restore the entire stack of fragments and objects passed to them and what does one do to prevent the original fragment from leaking?

Huppert answered 6/4, 2015 at 4:3 Comment(1)
Are you sure the onActivityResult is being delivered to old fragment? Have you tried logging the fragment object (this) in onCreate / onCreateView and onActivityResult? This will give you a clear idea on which fragment the onActivityResult is called.Enzymology
A
1

When your code executes following line :

startActivityForResult(photoPickerIntent, PHOTO_SELECT_REQUEST_CODE);

Your activity will get onPause(), onStop() but not onDestroy() everytime. If android system is out of memory at that run time then your activity may get onDestroy()

For saving state of fragment and activity and prevent leaking :

Save your state in onSaveInstanceState(Bundle)

In situations where the system needs more memory it may kill paused processes (after onPause()) to reclaim resources. Because of this, you should be sure that all of your state is saved by the time you return from this function. In general onSaveInstanceState(Bundle) is used to save per-instance state in the activity and this method is used to store global persistent data (in content providers, files, etc.)

Restore your state in onRestoreInstanceState(Bundle)

onRestoreInstanceState(Bundle) method is called after onStart() when the activity is being re-initialized from a previously saved state, given here in savedInstanceState. Most implementations will simply use onCreate(Bundle) to restore their state, but it is sometimes convenient to do it here after all of the initialization has been done or to allow subclasses to decide whether to use your default implementation. The default implementation of this method performs a restore of any view state that had previously been frozen by onSaveInstanceState(Bundle).

This may help you implement your requirement

Acridine answered 6/4, 2015 at 5:58 Comment(4)
thank you for your answer. I did implement the logic for re-creating the activity and fragments based on onSaveInstanceState/onRestoreInstanceState listeners. I am still however facing the "leftover" fragment issue. Since it's registered to receive activity result it's not going to be marked for GC and i can't think of a nice way to forward that result into the fragments that are re-created.Huppert
@DmitryGolomidov Did you find the answer? I'm facing the same issue.Carmencita
@Carmencita same issue here. Any news?Pages
Any solution i am facing same issue and i am using navigation componentCondolent

© 2022 - 2024 — McMap. All rights reserved.