Reputation: 55
I have read the two reasons/issue mentioned on:
(Please read two reason on below link)
Android AsyncTask for Long Running Operations
1. "If you start an AsyncTask inside an Activity and you rotate the device, the Activity will be destroyed and a new instance will be created. But the AsyncTask will not die":
Lets suppose i have set the orientation of my activity to Portrait. Will this issue still be there?
2. Memory leak issue:
inner class will hold an invisible reference on its outer class instance : the Activity.
What if i am not using Inner AsyncTask instead created separate class. Also if i use weak reference.
Upvotes: 3
Views: 1720
Reputation: 29436
The issues you mention arise only when life-cycle of AsyncTask is not handled properly, mainly from lack of understanding of how they work.
AsyncTask is a wrapper for running code on a separate thread. It is similar to plain Java's Runnable
submitted to ExecutorService
, with additional features of "pre" and "post" hooks to be run on main thread. So, its basically an enhanced version of Thread
, Runnable
and Handler
setup.
By default AsycTask's share a single thread and hence not advised for long running tasks. Because when a single background thread is shared by many tasks, a long running task may block others. However, AsycTask can also run on a custom Executor
, removing such restrictions of a shared worker thread.
All that means that AsyncTask's own design doesn't restrict its usage for long running tasks.
You can have a background Service
run some continuous processing using AsyncTasks on a separate ThreadPoolExecutor
.
You can have a Fragment
load latest news using an AsyncTask and when Fragment's onDestroy()
is called, you cancel the task, since its no longer meaningful.
Hence the answer to "how long and AsyncTask should run", entirely depends upon the usage context.
Upvotes: 4
Reputation: 12495
There are so many superstitions around this topic, it's hard to know where to start. AsyncTask
is just a small piece of sugar around a standard task queue, using it or not using it does not make much difference in comparison to other things.
For example the problem of orientation change is NOT real. You can start an AsyncTask
when the activity starts for the first time and simply not start it the next time around. (and remember that other changes in configuration can also restart your activity).
The weak references are a total overkill and will probably get you nowhere. You either need a reference to the current activity (and then the weak reference won't work) or not (and then, simply don't hold any reference).
The most important, and missing from your question, is what are you actually trying to accomplish?
Think about someone answering their phone while your application is running, and going back to it after some time. And then try to answer questions like: - are the results from 15 minutes ago relevant? Or will the task be restarted? - how about 6 hours ago? - will something bad happen if the background task is interrupted? - does user expect the task to be finished? (did he press "OK" and just waited for a confirmation to appear?).
And then you can ask a more precise question. AsyncTask
can be used in any scenario, but usually it's simpler not to use it than to use it correctly.
Upvotes: 0
Reputation: 622
Setting the orientation will work because locking to portrait means no orientation change, meaning no lifecycle re-creation because of this. However if an activity is paused for a long time it can still be destroyed so this is not a good way to make sure this works 100%. You could instead try a service or a headless fragment.
According to this post, having a weak reference will solve the memory issue
Upvotes: 1
Reputation: 3376
AsyncTask have following drawback.
1. Memory leak :- In inner class as well in seprate class you provide reference of your activity to AsyncTask for callback in both case AsyncTask will not release the reference of activity for GC which cause memory leak.
2. GC :- If a AsyncTask is running although the calling activity is destroyed it will restrict the GC to not run till it will not finish its process.
3. On Orintation change activity recreate as Asynchtask will running in background and when it finish its operation it will try to update UI which cause IllegalStateException as activity is not attached to window.
So its better if you use Service for long running background process instead of AsyncTask.
Upvotes: 0
Reputation: 5672
Additional problem of AsyncTask
: losing your results.
Yes, you said:
Lets suppose i have set the orientation of my activity to Portrait. Will this issue still be there?
But, Activity
could be recreated not only 'cause rotation. For example, if there is no enough resources in system, operation system can destroy your Activity.
So, for long running operations there is high risk that AsyncTask
will have an invalid reference to its Activity in onPostExecute()
after Activity recreation.
Another problem: parallelism.
new AsyncTask1().execute();
new AsyncTask2().execute();
Will these two tasks run at the same time or will AsyncTask2 start when AsyncTask1 is finished? Well... It depends on the API level.
And aboud API level...
Before API 1.6 (Donut): the tasks were executed serially. This means a task won't start before a previous task is finished.
API 1.6 to API 2.3 (Gingerbread): the Android developers team changed AsyncTasks to make possibility to start them in parallel on a separate worker thread.
API 3.0 (Honeycomb): the AsyncTasks where executed serially again. Of course the Android team provided the possibility to let them run parallel. This is done by the method executeOnExecutor(Executor)
. Check out the API documentation for more information on this.
Upvotes: 1