Kevin Pione
Kevin Pione

Reputation: 299

Android - NULL Activity From Thread

I have a Thread which simply does some HTTP work and signs a user in. If the thread returns whilst GetActivity is null, then I store the results in a workerFragment and pick them up again when the activity is re-created (such as a screen rotation during sign in.) This is so I can update the UI correctly via a handler.

The problem I am having is that there are occasions when rotating the device, that my code picks up that getActivity is null, so it should store the data. Then this data is never picked up from OnActivityCreated, almost as if it has already run?

My question is how can getActivity() be NULL if onAcitvityCreated has run and secondly, can I trust the LogCat to determine the order of events, as at the moment, my error logs put the Thread as returning always after onResume, but that doesn't seem right.

    @Override
public void onActivityCreated(Bundle bundle) {
    super.onActivityCreated(bundle);
    Log.d(Constants.LogTag, "Activity Created");
    //So here we want to start a new worker fragment that is only going to hold our signInData in the event that
    //we resume between activity destruction and creation
    fm = getFragmentManager();
    signIn_worker = (SignIn_Worker) fm.findFragmentByTag(TAG_TASK_FRAGMENT);

    //If it has not been set up, we set it up using the following:
    if (signIn_worker == null) {
        signIn_worker = new SignIn_Worker(); //Initialise it
        signIn_worker.setTargetFragment(this, TASK_FRAGMENT); //Set the target fragment to this, so we call back here
        fm.beginTransaction().add(signIn_worker, TAG_TASK_FRAGMENT).commit(); //Kick it off
    } else {
        //Fragment is not null, check if we have a sign-in pending
        if(signIn_worker.dataStored) {
            Log.d(Constants.LogTag, "Completing sign in on activity creation");
            completeSignIn(signIn_worker.success, signIn_worker.error);
            signIn_worker.dataStored = false;
        }
    }
}



public void signedIn(boolean success, String error) {
    Log.d(Constants.LogTag, "Signing in...");

    if(getActivity() == null) {
        //Getting access to our fragment manager and worker fragment here
        //Here we just store our results and we will check for them on activity creation
        Log.d(Constants.LogTag, "PROBLEM! Storing data in fragment. Acitvity Created");
        signIn_worker = (SignIn_Worker) fm.findFragmentByTag(TAG_TASK_FRAGMENT);



        if(signIn_worker == null) {
            Log.d(Constants.LogTag, "WORKER IS NULL?!");
        }

        signIn_worker.error = error;
        signIn_worker.success = success;
        signIn_worker.dataStored = true;
    }
    else {
        Log.d(Constants.LogTag, "Sign in went fine..");
        completeSignIn(success, error);
    }

}

The code examples are above. I have tried moving around the code within onActivityCreated to see if it makes a difference, but nothing will work. I get a feeling this is caused by the thread returning in between lifecycle calls, but I can't be sure!

Upvotes: 0

Views: 74

Answers (1)

BladeCoder
BladeCoder

Reputation: 12949

  1. Make sure you execute signedIn() on the main thread, otherwise everything can go wrong. That's why it's preferred to use an AsyncTask rather than a bare Thread.

  2. getActivity() will return non-null between onAttached() and onDetached(). So at some point it gets null again when the Activity is re-created. However, since you want to update a Fragment's UI, what you really want to check is if you have a view hierarchy in place or not: if getView() is not null. Because your fragment may be attached to an Activity but its view hierarchy may already have been destroyed when it is about to be detached.

  3. If you really want to do things right, you should use Loaders instead. They are meant to do what you're doing manually: they only deliver results to the Activity/Fragment while it's started and they can keep the result until the next start. They are automatically preserved when the Activity is re-created on configuration changes. But I won't deny they are hard to learn.

Upvotes: 1

Related Questions