14

I'm using fragments in my application. And the very common problem while using them are the NPE when using getActivity(). I know we can solve it by checking if getActivity() != null every single time or checking if the fragment isAdded().

In one of my classes I'm getting activity's context in more than 60 places. Checking if getActivity()is not null or if the fragment is still added to the activity in all the places is making the code ugly,larger and non-maintainable. Is there any other way to handle this? Is it even possible to destroy the fragment(and stop any work it has been doing while being removed) when it is removed from the activity?

Also Is this way a suggested one?

Community
  • 1
  • 1
LoveMeSomeFood
  • 3,137
  • 7
  • 30
  • 53

5 Answers5

13

In my experience, most cases of getActivity() returning null are in asynchronous callbacks.

For example, your fragment fires an AsyncTask, and then gets removed before the the background job is done, then when the background job finishes and calls getActivity() in onPostExecute(), it will get a null since the fragment is already detached from the activity.

My solution:

1.Check getActivity()==null at the beginning of every asynchronous callback, if it's the case then just abort the method.

2.Cancel asynchronous jobs in onDetach().

And I think this is a better solution than saving the activity instance in onAttach(), because since your fragment is removed, why bother doing all the jobs left in the callbacks(in most cases UI codes)?

handhand
  • 736
  • 7
  • 12
  • 1
    To me this seems to be the best solution.! – LoveMeSomeFood Apr 11 '17 at 16:06
  • Very good solution! This explanation is moreover not obvious! Good point! – JarsOfJam-Scheduler May 26 '19 at 18:16
  • Wow... This answer is the best. In my case getActivity() returns null sometimes and I didn't know when getActivity() returns null and how to handle this. Thanks to @handhand I realized that in my code getActivity() is in OkHttp Callback which works asynchronously. In addition I need to do nothing when getActivity() is null since the Activity and related Fragments are already gone. – mazend Jan 23 '20 at 10:59
4

getActivity will be reinitilized in method - onActivityCreated().

So it's safer to call getActivity() right after onActivityCreated() (according to lifecycle of fragments http://developer.android.com/guide/components/fragments.html) - for example in onStart() - in that case it's WILL BE NEVER NULL - no need to do useless checks like isAdded and getActivity != null.

P.S. If we use that solution:

@Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mActivity = activity;
    }

mActivity will be never null - but later in method onActivityCreated() getActivity() became different with mActivity. My opinion - sure we can save whole activity in variable, but it's safer to follow android fragments lifecycle workflow and get activity right after onActivityCreated()

Alexey O.
  • 220
  • 2
  • 11
  • If your fragment is static then there can be memory leak i have personally faced this issue. Never collect activity reference in fragment. If so forcefully mark it as null in onDetach() – silentsudo Dec 28 '15 at 09:47
  • Yeap, that's reasonable about activity even if it's not static. Also I never use the static fragments - it's just dangerous(like you said - memory leak) and I never saw a situation where it's could be useful. – Alexey O. Jan 04 '16 at 18:02
0

I think you should use the Fragment's onAttach(Activity) method.

I think that should help you avoid all of those NPE.

Embattled Swag
  • 1,479
  • 12
  • 23
0

My solution is override the onSaveInstanceState method in BaseActivity:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    //solution of fragment.getActivity() is null
    outState.remove("android:support:fragments");
}
luckybilly
  • 221
  • 1
  • 9
-1

I didn't found a solution to that, maybe because if you think about the lifecycle of a fragment you should be able to understand when you have check the null value.

Simone Casagranda
  • 1,217
  • 17
  • 26
  • 1
    Yup I understand that detached fragment is still alive :( I hope there is some way!! – LoveMeSomeFood Jan 14 '14 at 22:59
  • 1
    I see what you mean. Basically what I tend to do is to check my activity/context when I have done something asynchronous and I want to be sure that the fragment is still attached to the activity (for example checking if isAdded http://developer.android.com/reference/android/app/Fragment.html#isAdded()). But if you scroll at the middle-end of the linked page you'll find how to coordinate the two 'different' life cycles. – Simone Casagranda Jan 14 '14 at 23:06
  • Sorry I don't get what you are saying in the last line. – LoveMeSomeFood Jan 15 '14 at 16:15