An async task in a Fragment used to crash my app if the app was suddenly closed. The post execute code ran (e.g. show a Toast), but there was no app anymore.
I thought I fixed this by checking getContext() != null before running post execute code, but I got another crash.
java.lang.IllegalStateException:
at android.support.v4.app.Fragment.requireContext (Fragment.java:614)
at android.support.v4.app.Fragment.getResources (Fragment.java:678)
at android.support.v4.app.Fragment.getString (Fragment.java:700)
at com.grammarbud.android.grammarbud.MainFragment$2.onBillingServiceDisconnected (MainFragment.java:310)
I read that
Fragments now have requireContext(), requireActivity(), requireHost(), and requireFragmentManager() methods, which return a NonNull object of the equivalent get methods or throw an IllegalStateException.
https://developer.android.com/topic/libraries/support-library/revisions.html#27-1-0
Does this mean getContext() doesn't return null anymore? But then what does the below excerpt mean? Will it return null or not when not attached to the Activity? I don't understand the language.
The getActivity and getContext methods return nullable types because when the Fragment is not attached to an Activity, these methods already returned null. There's no change in behaviour, it's just explicitly marked now, so you can safely handle it.
https://stackoverflow.com/a/47253335/3268303
My code, which is run in a Fragment
private void connectToPlayStore() {
mBillingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(@BillingClient.BillingResponse int billingResponseCode) {
if (billingResponseCode == BillingClient.BillingResponse.OK) {
if (getContext() != null) {
queryProductDetails();
}
}
}
@Override
public void onBillingServiceDisconnected() {
// Line below ***CRASHES*** app if closed prematurely
SharedHelper.showToast(getContext(), getString(R.string.no_connection_to_play_store));
}
}
});
}
The SharedHelper function to show the Toast, which would catch if context is null, but execution doesn't get this far it seems to me
public static void showToast(Context context, String message) {
if (context != null) {
Toast newToast = Toast.makeText(context, message, Toast.LENGTH_LONG);
showToast(newToast);
}
}
So how to properly provide for the scenario when an async task is running in a fragment and the app is suddenly closed? Should I try to end connection with BillingClient.endConnection()? Will this guarantee that post execute code is not run? It doesn't explicitly say in the docs.
Also someone mentioned isAdded(). Should I check isAdded() instead of getActivity() != null && getContext() != null?