Android: AsyncTasks and Rotation

Recently i came across an interesting scenario.

  • User holds the app in landscape mode
  • Performs an action that kicks off an async task (the task upon completion displays a notification to the user)
  • Before the task completed, the user changes the orientation to portrait mode.
  • I would expect the background task to continue doing whats its supposed to do, and give me a notification when its done.
  • But no notification was observed. Did the task complete? Why was there no notification (error or success)

After further digging into this scenario, i realized that even though the async task completed, it was unable to attach it self back to the calling fragment because the fragment was destroyed and recreated again due to the rotation. Oh crap.

Handling screen configuration changes has become the bane of Android development for me. But it also poses a good challenge. What happened here and how best to overcome this. I had to do some research.

Turns out its a pretty straightforward concept.

First, there are two things we need to understand about loaders.

            public abstract <D> Loader<D> initLoader(int id, Bundle args,
            LoaderManager.LoaderCallbacks<D> callback);

starts a new loader with the given id, or tries to re-connect with an existing loader with that id.

public abstract <D> Loader<D> restartLoader(int id, Bundle args,
            LoaderManager.LoaderCallbacks<D> callback);

starts a new loader with the given id OR, re-start an existing loader with that id.

This means if i call restartLoader, it will re-execute that task again in the background. If i call initLoader, it will  NOT re-execute that task again but simply return the result if that loader has finished its job.

To handle the rotation missing async task problem, the trick here is when onActivityCreated() is called after rotation, we need to call initLoader with the id to re-connect with our loader and get back the result of our async task. If we don’t do that, our async task would have executed, but we would had no idea that it did and onLoadFinished() would never be called. And in my case display a never ending “loading…” dialog.

Here’s a link that helped me figure it out -> http://android.codeandmagic.org/2011/07/android-fragments-saving-state-and-screen-rotation/

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s