Reputation: 1590
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
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
Reputation: 5742
Fragment lifecycle is too complex and complicated
Activity myactivity = getActivity();
if (isAdded() && myactivity != null) {
...
}
Upvotes: 0