Cameron
Cameron

Reputation: 1590

java.lang.IllegalStateException: Fragment not attached to a context after API response

In my app, I have a fragment that I'm using to display data, and a Settings activity that I use to change some settings in the app. When I go to the settings activity via the navigation drawer, and then return to the main screen (without changing settings), the app crashes with this exception:

java.lang.IllegalStateException: Fragment NowWeatherFragment{b7914f8 (0e67ee0d-8776-45b5-9fd7-ee69841c31d1)} not attached to a context

It seems to be happening after a response from an API call, and there was a decent explanation of why from another answer on SO, but nothing I've tried has been able to fix that.

I have seen several other questions about this, but I'm having trouble applying the answers to them to my situation. I tried checking for isAttached() and that didn't help, as well doing a null check for the fragment, but it's still getting the same exception

Rather than post all of the classes, some of which are very long, here is the github repo. It should be fairly lightweight and easy to run on a device through Android Studio https://github.com/jollygreenegiant/SimpleWeather

I expect that the app will just go back to the main screen and display the weather data like it does on launch.

Here is the full stack trace:

java.lang.IllegalStateException: Fragment NowWeatherFragment{b7914f8 (0e67ee0d-8776-45b5-9fd7-ee69841c31d1)} not attached to a context.
        at androidx.fragment.app.Fragment.requireContext(Fragment.java:765)
        at androidx.fragment.app.Fragment.getResources(Fragment.java:829)
        at com.jggdevelopment.simpleweather.fragments.NowWeatherFragment.setupViews(NowWeatherFragment.java:82)
        at com.jggdevelopment.simpleweather.fragments.NowWeatherFragment$3.onSharedPreferenceChanged(NowWeatherFragment.java:152)
        at android.app.SharedPreferencesImpl$EditorImpl.notifyListeners(SharedPreferencesImpl.java:612)
        at android.app.SharedPreferencesImpl$EditorImpl.commit(SharedPreferencesImpl.java:598)
        at com.jggdevelopment.simpleweather.fragments.MasterFragment.updateConditions(MasterFragment.java:263)
        at com.jggdevelopment.simpleweather.services.WeatherAPIUtils$2.onResponse(WeatherAPIUtils.java:92)
        at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1$1.run(DefaultCallAdapterFactory.java:83)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7319)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:934)

Upvotes: 3

Views: 4468

Answers (2)

ianhanniballake
ianhanniballake

Reputation: 200080

You need to call unregisterOnSharedPreferenceChangeListener() in your onDestroyView() (the mirror of onCreateView(), which is where you register the listener).

As it is now, you're leaking your Fragment as SharedPreferences holds a strong reference to your listener, continuing to send it callbacks to its onSharedPreferenceChanged well after your Fragment's view is destroyed, causing the error message you're getting.

Upvotes: 5

Chanaka Weerasinghe
Chanaka Weerasinghe

Reputation: 5742

Fragment lifecycle is too complex and complicated

Activity myactivity = getActivity(); 
if (isAdded() && myactivity != null) {
...
}

Upvotes: 0

Related Questions