Does AsyncTask really do things in background? - android

I used AsyncTask to get html files from server. But when an activity starts, screen becomes white few seconds and displays data when fully downloaded.
I wanted it to display activity's basic layout first(e.g. actionbar) and downloaded data later. So I used Thread and the problem solved.(basic layout is first shown and data later)
I've been knowing AsyncTask do things asynchronously but in my case it didn't.(In doInBackground, I only did network connection)
Does AsyncTask really do things in background?

Does AsyncTask really do things background?
Yes.
Note, though, that AsyncTask is serialized by default, meaning that if you fork multiple AsyncTask instances, they will share a single thread, and the second and subsequent tasks will be queued up waiting until the first task completes. You can avoid this via using executeOnExecutor(), instead of execute(), to run the tasks.
There are other ways of misusing AsyncTask (e.g., calling get()) as well.

Related

Executing a Thread in Asynctask and its complications

I was wondering is it ok to execute a Thread inside the doInBackground method of Asynctask. Should I avoid using this kind of structure on my codes? And if yes, why should I avoid it? Would this cause any ineffectiveness in my apps?
In principle, there's no problem with starting a thread in the doInBackground() of an AsyncTask, but sometimes you see this done not because it's the right thing to do, but because of a misunderstanding about how AsyncTask works.
The point is that doInBackground() will automatically get executed on a background (non-GUI) thread, without you needing to create a thread for it yourself. That, in fact, is the whole point of an AsyncTask. So if you have a simple, linear task that you want executed in the background, you do it with an AsyncTask, and you don't need to do any manual thread creation.
Where you might want to start a new thread in an AsyncTask is if you want your background task to use multiple threads to complete. Suppose that you were writing an app to check the online status of various servers, and display something about their status on the screen. You'd use an AsyncTask to do the network access in the background; but if you did it in a naive way, you'd end up with the servers being pinged one by one, which would be rather slow (especially if one was down, and you needed to wait for a timeout). The better option would be to make sure that each server was dealt with on its own background thread. You'd then have a few options, each of which would be defensible:
Have a separate AsyncTask for each server.
Create a thread for each server inside the doInBackground() of your single AsyncTask, and then make sure that doInBackground() doesn't complete until all the individual threads have completed (use Thread.join()).
Use a ThreadPool / some kind of ExecutorService / a fork/join structure inside your single AsyncTask, to manage the threads for you.
I would say that with modern libraries there is rarely a need for manual thread creation. Library functions will manage all of this for you, and take some of the tedium out of it, and make it less error-prone. The third option above is functionally equivalent to the second, but just uses more of the high-level machinery that you've been given, rather than going DIY with your thread creation.
I'm not saying that threads should never be created manually, but whenever you're tempted to create one, it's well worth asking whether there's a high-level option that will do it for you more easily and more safely.
is it ok to execute a Thread inside the doInBackground method of
Asynctask.
yes it is but it really depends on your application and your usage. for example in a multithread server-client app you must create for each incoming clients one thread and also you must listen on another thread. so creating thread inside another is ok. and you can use asynctask for listening to your clients.
Should I avoid using this kind of structure on my codes? And if yes,
why should I avoid it?
If you design it carefully you do not need to avoid, for example make sure that on rotation you do not create another asynctask because for example if your user rotates 5 times you create 5 asynctasks and in each of them you create a thread that means you will get 10 threads, soon you will get memory leak.
Would this cause any ineffectiveness in my apps? Can you explain
these questions please.
I answered it above, I think better idea is using Thread Pool to minimize number of creating your threads or wraping your asynctask in a UI less fragment so you are sure you have one asynctask regardless of whats going to happen.
In any higher programming language, there is concept of multi-tasking. Basically the user needs to run some portion of code without user interaction. A thread is generally developed for that. But in Android, multi-tasking can be done by any of the three methods Thread and AsyncTask.
Thread
A thread is a concurrent unit of execution. It has its own call stack. There are two methods to implement threads in applications.
One is providing a new class that extends Thread and overriding its run() method.
The other is providing a new Thread instance with a Runnable object during its creation.
A thread can be executed by calling its "start" method. You can set the "Priority" of a thread by calling its "setPriority(int)" method.
A thread can be used if you have no affect in the UI part. For example, you are calling some web service or download some data, and after download, you are displaying it to your screen. Then you need to use a Handler with a Thread and this will make your application complicated to handle all the responses from Threads.
A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each thread has each message queue. (Like a To do List), and the thread will take each message and process it until the message queue is empty. So, when the Handler communicates, it just gives a message to the caller thread and it will wait to process.
If you use Java threads then you need to handle the following requirements in your own code:
Synchronization with the main thread if you post back results to the user interface
No default for canceling the thread
No default thread pooling
No default for handling configuration changes in Android
AsyncTask
AsyncTask enables proper and easy use of the UI thread. This class allows performing background operations and publishing results on the UI thread without having to manipulate threads and/or handlers. An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread.
AsyncTask will go through the following 4 stages:
1. onPreExecute()
Invoked on the UI thread before the task is executed
2. doInbackground(Params..)
Invoked on the background thread immediately after onPreExecute() finishes executing.
3. onProgressUpdate(Progress..)
Invoked on the UI thread after a call to publishProgress(Progress...).
4. onPostExecute(Result)
Invoked on the UI thread after the background computation finishes.
And there are lot of good resources over internet which may help you:
http://www.vogella.com/articles/AndroidBackgroundProcessing/article.html http://www.mergeconflict.net/2012/05/java-threads-vs-android-asynctask-which.html
I would say there is no problem in doing that if you need something to run concurrently beside the AsyncTask.
One issue could be one of readability (using 2 different ways for concurrency), but I really can't see the harm in that - especially if one of the tasks needs to show it's result in the UI and the other one doesn't.

Guideline to choose among AsyncTaskLoader and AsyncTask to be used in Fragment

Look at LoaderCustomSupport (Use AsyncTaskLoader) and FragmentRetainInstanceSupport (Use Thread, almost equivalent to AsyncTask)
Both examples have the following similarities.
Both do not block UI thread when loading data
The data fetching thread is not destroyed when user performs configuration change like screen rotation.
When data fetching thread finished fetching data, it can update to the correct Fragment UI
However, there are differences.
AsyncTaskLoader
Seems like there is no easy way to update intermediate progress to a progress bar dialog
AsyncTask
Not sure on this. But Android documentation seems to recommend AsyncTaskLoader for async data loading and updating final result to UI?
Is there any guideline, or checklist to look at, to make a decision on whether to choose AsyncTaskLoader or AsyncTask, to do a time-consuming loading task and update the result to Fragment's UI?
your question made me interested and tried sometimes to look into the differences. Here i am writing my observations.
For the premature termination the asynchronous task using AsyncTask will continue running in its thread. The processing of the results can soon lead to unrequested results while AsyncTaskLoader handle the premature termination of the activity
AsyncTaskLoader handles activity configuration changes (IE when the user rotates the screen).
AsyncTaskLoader is intended load data for DataAdapters so for this purpose it is best to use AsyncTaskLoader But if you need to change UI (specially fragments) after task completion it is better to use AsyncTask as you can't change fragments in onLoadFinished of AsynTaskLoader.
So to me the usage depends on your task. and if the above 3 points doesnt bother you then the performance is same ( haven't found any documents though , but in this case asynctaskloader is recommended :S)
some related links
AsyncTaskLoader vs AsyncTask
http://andreas-kluck.blogspot.com/2012/02/asynctask-and-asynctaskloader.html
AsyncTaskLoaders, like all Loaders, are intended to solve the rotation problem, which is when an AsyncTask is created on an Activity, then the device is rotated before the task has completed that AsyncTask will be lost with the destruction of the Activity.
It's true that all Loaders currently don't support publishing progress, so if this is a requirement for your situation then you should consider an alternative. If rotation, or any other event that causes the Activity to be destroyed, isn't an issue then just use an AsyncTask, otherwise you might want to use a Service, and register a binder to push progress messages back and forth.
Service and Binder messages are kind of a pain though, in my opinion. I find a much easier solution is to use LocalBroadcastManager to send progress broadcasts from an IntentService (or AsyncTaskLoader) and have a BroadcastReceiver in the Activity receive the broadcast and display the progress.

Android: How to retain AsyncTask instance when Activity gets destroyed?

In my app, I have a class that inherits from AsyncTask and which downloads huge amounts of data from the server. I am using a ProgressBar to indicate the progress of the download.
When the user hits the HOME key, the Activity to which this AsyncTask is attached, is destroyed but, download goes on.
How can I reattach this AsyncTask and show the progress to user? I tried using onRetainNonConfigurationInstance but Android 4.0 doesn't seem to invoke this method. My application does not use Fragments API.
What I did in this situation was as follows:
I created an IntentService to handle communication with the server. This has some of the benefits of AsyncTask (e.g., worker thread), but also some benefits of a Service (available any time, from anywhere).
The IntentService can be invoked either by a user action in my main Activity, or via an inexact repeating alarm.
The data is stored in an SQLite database, fronted by a ContentProvider. I dodge the issue of when/how to create my database and tables by using an SQLiteOpenHelper and calling getWritableDatabase() from the safety of my background IntentService.
When the task is done, it posts a Notification if my main Activity is not active.
One nice thing about this arrangement is, no progress bar is necessary. In fact, no UI is necessary. The user keeps using the application while the service is running, and the UI automatically refreshes itself as new data comes into the ContentProvider. Another nice aspect of it is it's less code to write than an AsyncTask. It automatically picks up where it last left off by reading the server-side metadata of the last entry from the database and asking the user to start after that point. Since it's not tied to any Activity instance, it doesn't care about onPostExecute() or configuration changes or any of that. And you don't have to worry about single-shot execution like AsyncTask.
If there is a need to download huge amount of data in background I would use service rather then AsyncTask. There is a good presentation from Google IO about using services.
Quote from AsyncTask documentation:
If you need to keep threads running for long periods of time, it is
highly recommended you use the various APIs provided by the
java.util.concurrent pacakge such as Executor, ThreadPoolExecutor and
FutureTask.
and
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
As I understand, you cannot proceed with your last AsyncTask.
Still, you can load your data partially and save amount of data read and then start new AsyncTask which will start from last saved point. From my point of view this is not the best idea to pause loading when activity goes to background and it is better to use service to finish what was started.
Have you considered using a service to attach your AsyncTask to? Seeing as a permanently running service would probably be the best solution for your task at hand. All you'd have to do then will be to check if the service is running and if your download is running (easily done using static boolean variables) then you just create a progress dialog using some state saving variable in your service (maybe a percentage of the total file size downloaded etc.) in the onCreate method of your main activity.

What is the difference between Handler (MessageQueue) and AsyncTask (SERIAL_EXECUTOR), performance wise?

There are a couple ways of getting data Asynchronously in your app. One is a Handler and another one is an AsyncTask. Now I've used both, and would like to know which one performs better/more efficiently at some tasks.
Thusfar, I've mostly used AsyncTasks in getting Webdata, and Handler's in getting data from Services to Activities.
I would like to know if there is an advantage to using Handler's for Webdata, or using AsyncTasks for refreshing UI from Services. What is the big difference?
Since AsyncTask uses a Handler, your comparison is... odd.
AsyncTask is great for transactional work: stuff that will take more than a few milliseconds and less than a few minutes. For that sort of work, if you have no need for your own thread management, AsyncTask is generally simpler to use.
If you have some particular characteristics that you need for your threading that AsyncTask will not readily handle, or if you need the thread for an indeterminate period of time (e.g., until the user presses a Stop button), use your own thread and something else to get work to the main application thread: a Handler, or post(), or runOnUiThread(). The "indeterminate period of time" recommendation assumes you are using one of the built-in thread pools -- I am never a fan of tying up a thread out of a thread pool that you didn't set up.
Looks like AsyncTask uses its own internal Handler. My testing is the "post" using a Handler is enqueued immediately. When used in onCreate this can be problematic as other actions must be enqueued after onCreate (haven't read through Android Activity etc source on this yet). So, trying to post to later load the layout did not work. Had to use an AsyncTask. Since AsyncTask has its own internal Handler; perhaps, then creating the task might occur in the queue directly after onCreate but the doInBackground and onPostExecute might occur later as they are later in a queue.
So, AsyncTask worked better for this UI need to load an overly large layout file later with setContentView - later meaning after the onCreate so a ProgressDialog could be shown. ProgressDialog doesn't show up until onCreate is done.
Also, see this article for how to choose when to use AsyncTask. Basically says when wanting to update UI. But actually you can do this with runOnUIThread so don't really need handler nor AsyncTask if you already know Java threading. runOnUIThread is like the invoke/invokeLater stuff in Swing.

Activity won't start until data is pulled from MySQL server

I have an Activity that displays a text based on data pulled from MySQL server. The problem is that the Activity won't load until data is pulled, which sometimes takes some long seconds or even doesn't load at all, and in the meantime the users gets a black screen.
I tried to pass the mission of getting the data from the server to a service, but also it waits for pulling the data and only then shows the layout of the Activity.
I also tried to make an activity with fixed text and then call the Activity that pulls the data from the server, but still the program wait for the data.
Can you think on a creative solution for it? or maybe a non-creative one as well :)
you can use asynctask for this:
http://developer.android.com/reference/android/os/AsyncTask.html
or you can show a waiting dialog to user until you get your data(do it in separate thread).....
or you can implement a splash screen and there you can fetch data.....
You need to do it inside another thread. Try using AsyncTask class.
The delay is probably due to the call to fetch the data being done on the main thread, also called the UI thread. Processes which take any significant amount of time, and by that I mean even a second or two should be done in a seperate thread. Android provides a class called AsyncTask to help make threading painless.
You mention you tried a service but did you take a look at an IntentService? (Can't link it yet but it's on d.android.com.) I like using them for these kind of tasks cause they handle the threading for you (like an AsyncTask) and it separates concerns better. The IntentService then sends a broadcast message that the activity picks up indicating that the data is available or not. Store the data locally in a sqlite db or as a json/xml file.

Categories

Resources