Android Fragment isAdded returns false and getActivity is null after posting thread in the onResume method

889 views Asked by At

So i am using Navigation in my main activity of my app and i have a fragment which is my start navigation fragment.

In this fragment, after it is created, in my presenter i post a thread to fetch data from the network. After data have been fetched, i am using the main thread to show the data to my screen.

The first time that the app runs, this is working fine.

However if user opens the drawer and selects again THIS fragment and not another one, fragment is recreated again meaning that it gets destroyed and created from scratch as Navigation Component is designed to do.

However this time, when my presenter posts thread fetching-data-thread and this gets finished and sends the results to the UI, fragment's isAdded() method returns false as well as getActivity is null.

Having that, means that i can't use the Activity Context (getActivity() is null or requireActivity() throws an illegal state exception) and consequently i cannot load images etc since i don't have the context available.

I highlight that this happens when user opens the drawer while this fragment is visible and selects again to navigate to this fragment from the drawer. In case that user navigates to another fragment and then presses the back button everything is ok.

Any idea how to handle this problem?

2

There are 2 answers

0
jvoyatz On BEST ANSWER

So, after testing and searching i found out the origin of the problem i described above.

I am nullifying my presenter's view in onDestroy/onDetach method of my Fragment. However when the replacement Fragment gets created, this new Fragment is firstly attached to the calling Activity and then, the old one gets destroyed.

Having in mind, that i inject my presenter into the Fragment instance, my presenter will be never null at the time that new Fragment gets attached and consequently, and considering that i create a new instance of my Presenter when it is null, the presenter instance that is being injected into the fragment is not aware of the new 'View' object.

As a result, when the results reach the UI thread through the callback this view object is 'not Added'.

3
Yrii Borodkin On

Fragments are meant to be destroyed, as well as activities. You can never rely on android framework component lifecycle state, and because of it android architecture components were made. ViewModel, for example, can outlive it's host fragment.

But - viewmodel/presenter/controller is not a right place to perform network request and handle app logic, just because it's not their job (SOLID's S-single responsibility).

There is official guide to app architecture. Simply speaking, you have a layer for android-related code, where you update UI, layer for handling app logic (which is java/kotlin and android framework independent) and layer for requesting/holding data. So, during creation of your ui class you obtain viewmodel, which has reference to class that handle logic and exposes result to render in ui. Inner layers are persisted - view is not.