質問

I'm trying to understand under what circumstances can getActivity() return null in a fragment AFTER onAttach. I typically start an async task in onCreate or onCreateView inside my fragments but I'm getting error reports indicating sometimes getActivity() is null when the async task finishes. Error reports are coming in via crashlytics but can't reproduce them.

The async tasks are "blocking" - I display a modal non-dismissable progress bar. Also rotation is prevented by calling setRequestedOrientation.

I'm using v4 support Fragment and FragmentActivity. Fragments are set to retain state.

What am I missing? Are there other config changes that may cause the fragment to be detached?

I tried temporarily enabling rotation and the dev option to destroy activity after leaving it but still can't reproduce this...

Here's some of the relevant code inside one of my fragments, in this case it would sometimes break with an NPE at activity.dismissSpinner:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    checkIfLoggedIn();
}

public void checkIfLoggedIn() {
    LoginActivity activity = (LoginActivity)getActivity();
    activity.showSpinner("Connecting, please wait...");

    AsyncTask<String, Void, JsonResponse> asyncTask = new AsyncTask<String, Void, JsonResponse>() {
        protected JsonResponse doInBackground(String... notused) {
            return cmsServer().getCurrentUser(getActivity());
        }

        protected void onPostExecute(JsonResponse result) {               
            LoginActivity activity = (LoginActivity)getActivity();
            activity.dismissSpinner();
            //...more stuff here
        }
    };
    asyncTask.execute();
}
役に立ちましたか?

解決

Do you stop/cancel your AsyncTask if your app goes to background or is paused?

Consider the following scenario: your AsyncTask is executed, and when prompted with the progress bar, the user decides to do other stuff while she waits for the task to complete. She does so by pressing the home button. Alas, this might destroy the fragment and the activity. The running AsyncTask knows nothing about it, and when done, getActivity() method invocations (or local variables pointing to a non-existent Activity) may as well return null, causing your app to crash.

他のヒント

The Fragmentlife cycle is as follows

Fragment life cycle

According to Fragment life-cycle onCreate() and onCreateView()are called before the Activity creation. so when we call getActivity() in these methods in returns null. so instead of starting the async task in the onCreateView() start it in onStart() or onResume() so that getActivity() returns the exact Activity reference.

For more details click here

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top