4

How to retain async task during screen oreintation. I have searched it much but not found any elegant solution to it.

What are my issues ::

  1. I am having different layouts for portrait & landscape so cannot use android:configChanges="keyboardHidden|orientation|screenSize" to restrict activity recreation.

  2. I cannot use Fragment.setRetainInstance(boolean) as I am having nested fragments so I am adding fragments to back stack using addToBackStack()

    In this situation :

    onCreate() and onDestroy() are not called. This is metioned in the API docs.

    A bundle passed from onSaveInstanceState() is not received in onCreateView(). The passed-in Bundle is null. So I will not get the saved instance of the activity

How to retain a async task in fragments to avoid crashing on orientation change.

Or is there any other way for performing asynchronous task.

Dory
  • 7,462
  • 7
  • 33
  • 55
  • Sorry if i don't understand, retain task means async task is not start again after orientation? OR u want to pass data to async taks after orientation? – Neha Mar 11 '14 at 08:46
  • @Neha i dont want to start again async task again on screen orientation.. Old one which is ongoing should we working instead of giving any memory leak as the old activity is destroyed. – Dory Mar 11 '14 at 08:51
  • So as per ur #1 point every time at orientation u destroy the current activity and start new (base on portrait/landscape mode). And bcaz of it ur async task lost bcaz activity which started is destroyed. So memory leak is issue Or u don't know from where async task need to start like data lost.? – Neha Mar 11 '14 at 08:59
  • This questiion could be useful http://stackoverflow.com/questions/8417885/android-fragments-retaining-an-asynctask-during-screen-rotation-or-configuratio?rq=1 – Narkha Mar 11 '14 at 08:59
  • @Neha async task is lost becoz activity would be destroyed. – Dory Mar 11 '14 at 09:01
  • I believe your first asumption is false. Can't you handle `configChanges` and on configuration change loading the appropriate layout ? – Antoine Marques Mar 11 '14 at 09:20
  • @AntoineMarques yes that can be done. but for it i need to remove older view and loader new layout according to orientation which sometimes slow downs rendering.. and shows new layout after a lag.. – Dory Mar 11 '14 at 09:24
  • As i not tested it but a suggestion u can implement OrientationEventListener and on orientation change cancel the async task and start it again on new activity onCreateView(). – Neha Mar 11 '14 at 09:29
  • @Neha thnks buddy for suggestions but cancelling async task and restarting again could cause task to run long,by again n again restarting task. As screen orientation change can be frequent. – Dory Mar 11 '14 at 09:32
  • @Jewel sorry its not useful another suggestion is temporarily locking the screen in onPreExecute(), and unlocking it in onPostExecute(). Though this will change behave (make sense if your task progress bar/or loading screen). – Neha Mar 11 '14 at 09:40

2 Answers2

0

If you can't use a retain instance of a Fragment you should use a Service or an IntentService to run your Task. The idea of a Service is that it keep processing independent what happens in an Activity. Because you didn't say someething about the Tasks work, decide which one fits best to your App.

To run an AsyncTask in an Activity is usually a bad idea, because of the fact that the Activity can be destroyed by the system or while orientation changes. Now there are plenty of work arounds out there to deal with this, like the retain Fragment approach. But these are having some disadvantages, like the onSaveInstanceState() point you noted. And all work arounds deal with the same thing: keeping the reference.

I don't know why it's not very popular to use a Service, which is the easiest way to run an async task (of any kind) without getting headaches while thinking about how to hold a reference to it.

Steve Benett
  • 12,843
  • 7
  • 59
  • 79
  • thnks for response. Can we display any kind of progress notification while using service. I am not having idea of it. What about using `Loader` instead of `AsyncTask`. Any comment on using it. – Dory Mar 11 '14 at 09:30
  • You can use [Notifications](http://developer.android.com/guide/topics/ui/notifiers/notifications.html), which is the recommended way by the design guides. – Steve Benett Mar 11 '14 at 09:35
  • but i will not able to freeze fragments using notifications. As my fragment data will be dependent of the data from web servies. If I use services for it than how would I manage it. – Dory Mar 11 '14 at 09:38
  • Try [this tutorial](https://www.websmithing.com/2011/02/01/how-to-update-the-ui-in-an-android-activity-using-data-from-a-background-service/) to see how to provide the data from a Service to the Activity. – Steve Benett Mar 11 '14 at 10:02
  • Ohh yes using receivers we can update data. But i guess we cannot show any progress dialog while service is ongoing the background task. – Dory Mar 11 '14 at 10:08
  • Why not? If the Activity is visible you can update a ProgressBar with onProgressUpdate() in your AsyncTask using a callback. – Steve Benett Mar 11 '14 at 10:16
  • you suggested toswitch on services rather than `AsyncTask`. My doubt was how to show progress in actvity while using servies for asynchronous task. – Dory Mar 11 '14 at 10:27
0

Alternatively, you could try launching your AsyncTask in its own task (see Intent.FLAG_ACTIVITY_NEW_TASK) so its lifecycle becomes independent of your Activity being destroyed, then recreated.

You can then comunicate with using a Handler for retrieving results and/or progress.

Antoine Marques
  • 1,379
  • 1
  • 8
  • 16