Android thread queue - android

I'd like to have a queue of work/tasks to be done on a separate thread, but can only process one work at a time. So not simultaneously.
Is there something built-in android for this?
Thanks,
EDIT:
The work = get information from Database. Once done, update the UI with the fetched information.

Have you checked out java.util.concurrent.Executors ? You could do something like this:
final static ExecutorService tpe = Executors.newSingleThreadExecutor();
...
tpe.submit(new Runnable() {
#Override
public void run() {
// your work
}
}):
It's not android specific, it is part of the jdk5.
From the doc:
Creates an Executor that uses a single worker thread operating off an
unbounded queue. (Note however that if this single thread terminates
due to a failure during execution prior to shutdown, a new one will
take its place if needed to execute subsequent tasks.) Tasks are
guaranteed to execute sequentially, and no more than one task will be
active at any given time. Unlike the otherwise equivalent
newFixedThreadPool(1) the returned executor is guaranteed not to be
reconfigurable to use additional threads.

If you want something can do work independently from the activity lifecycle that can do queued work, you should take a look at IntentService. It can spin up, do discrete blocks of work asynchronously then finish itself when all its tasks are completed.
If you don't need anything that can live without any activities, Java has ExecutorService along with several different implementations.

In Android You can also consider about Loader framework.
http://developer.android.com/guide/components/loaders.html

Related

Cancel AsyncTasks from collection

Let's say I have TasksManager which has static List tasks (not sure list is good solution) and there are static methods addTaskToList(MyTask task){tasks.add(task);},
removeTaskFromList(MyTask task){tasks.remove(task);}
Each task in doInBackground() calls first method, and in onPostExecute() there is second method call with "this".
MyTask has String field "method".
I want to cancel tasks of this list where task.getMethod().contains("url")..
not sure this code is good enough for stable working.. looks like onCancelled() of task not always called, multitreading can be dangerous for such methods I think.
for (MyTask task : tasks) {
if (task.getMethod().contains("url")) {
task.cancel(true);
break;
}
}
Is it normal practice to store tasks in this way or you can suggest me more elegant?
Cancelling an AsyncTask isn't always an immediate/obvious thing. If you are using cancel, you also need to make sure doInBackground is aware of isCancelled and you have to stop what you were doing yourself (see the docs for isCancelled).
I wouldn't recommended storing a list of AsyncTask objects and iterating them for doing sequential background work anyway. That sounds like it might get very messy very quickly. Each AsyncTask creates a new Thread, and that doesn't sound like what you want. Rather, you may just want one background thread you can do stuff on?
For one background thread you can use a HandlerThread and your own Looper, as follows:
HandlerThread backThread = new HandlerThread("BackLooper", Thread.NORM_PRIORITY);
backThread.start();
Looper backLooper = backThread.getLooper();
private synchronized void runOnBackThread(Runnable r) {
new Handler(backLooper).post(r);
}
Then each item you want to run in sequence you can post on the back thread by submitting a Runnable. And, you can also use the other Handler post variants too, postDelayed, postAt, and so on.
And, depending on what you're doing you may find IntentService very helpful. IntentService is provided specifically for a "work queue" type pattern. It has one background thread, does whatever you tell it to do ONE AT A TIME when you invoke it, and goes away on its own when it's not needed.
Lastly, if you're looking for a really nice general "task" type library for Android check out Square's Tape. That's not directly related to your question, but I find Tape super handy for more robust "queue it up" task type situations.

If I start an AsyncTask during onCreate, when will it begin execution?

I want to ensure that I don't slow down my app's startup time and need to start a background task that's unrelated to user input--for instance, filling a cache.
If I start an AsyncTask from my onCreate method, when will the doInBackground method actually begin to execute? (Assume a single core device)
Is it possible that Android could schedule it before onCreate/onResume has completed, or is it smart enough to recognize that the background thread shouldn't run until the UI thread is completely finished?
If you look at AsyncTask source code you will see that it is just using ThreadPoolExecutor or serial executor for running tasks. Default internal behavior depends on Android version (from AsyncTask docs):
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.
But anyway doInBackground execution is not connected with Activity lifecycle so AsyncTask may be executed at almost any time. This depends only on how many tasks you have already started, on default Executor which is used by AsyncTask and on thread scheduler.
I usually use AsyncTasks in onCreate() like this:
private MySuperSpecialTask mySuperSpecialTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(...);
// [...]
mySuperSpecialTask = new MySuperSpecialTask();
mySuperSpecialTask.execute();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mySuperSpecialTask != null) {
mySuperSpecialTask.cancel(true);
}
}
This makes sure that everything is initialized before the task gets started.
actually strictly speaking there is no execution order of your UI code and starting the asynctask I found out. Normally one does not experience this, however, if your UI thread takes longer for some reason, eg waiting for external input etc, the asynctask might have gotten started BEFORE UI code has finished.
Writing UI code is just a request to the Android system and this waits in the execution loop. So if asynctask starts before that because there are enough ressources (or as mentioned UI thread is delayed for whatever reason) there is no execution order guarantee.
One easy way to enforce this is - in case you don't mind and you can be sure that it is suffiencient - delay the starting of the asynctask with ScheduledExecutorService or a "cleaner" way would be to implement some kind of gate keeper that waits for a flag to be set to true and then start the asynctask. Or you may even have a while-loop at the beginning of your asynctask that waits for the flag to be set to true, like in many communication situations with external devices.
The flag would be set to true AFTER you can be (normally) sure that your UI has finished.

Implementing a cyclic executive in android?

I am writing an android app and I need to be able to do certain things periodically/continuously. I am coming from a C/C++ embedded firmware background and this new-fangled way of doing things is going to take some getting used to. It seems that there is no such thing as a "main loop" in Android, that everything is event-driven... I also understand that by default all code you write operates on the GUI thread, and I should probably make a new thread to execute the equivalent of a "main loop"...
So far what I have is an implementation of the AsyncTask class who's "doInBackground" method contains an infinite loop (my main loop), I create an instance of this class and run it immediately when my app starts. The problem I am having is in the interaction between this thread and the user interface... when something occurs in my main loop thread and I want to update the GUI understand that I must call "publishProgress", which is executed on the GUI thread. There are a few problems with this, primarily that many things I have tried to do in this "onProgressUpdate" method do not work, or do not occur in a predictable amount of time.
My question, is there a better way to accomplish what I am trying to do? In general, what do most people do when they have code that they want to run periodically and/or continuously while their application is running, code that must interact with the user interface in a timely manner (by timely I mean with zero delay).
Thank you.
public class MainLoopThread extends AsyncTask<Void, Void, Void>
{
#Override
protected Void doInBackground(Void... arg0)
{
while(true)
{
//Do stuff
//Update GUI
publishProgress();
}
}
protected void onProgressUpdate(Void...voids)
{
//Update GUI
}
}
It is unclear what you are trying to do, however just let me say using AsyncTask in this way may have negative consequences.
AsyncTask internally uses a thread pool pattern for running the stuff from doInBackground(). On Android OS before 1.6 and starting from 3.0 the pool size is just 1, meaning no parallel computations for a bunch of AsyncTasks. More details on this here.
So, this may result that only this current AsyncTask is running, while others even if started will have to wait untill the current one is done.
Depending on your needs for things to be done periodically Android exposes:
AlarmManager
Handler - it allows to post a runnable on UI thread with a delay or periodically
Timer + Activity.runOnUiThread(Runnable action) inside of TimerTask
UPDATE: basing on your comments it looks like you need a Service, that starts a thread that periodically sends broadcasts with the data for UI. Then your UI (Activity) registers broadcast receivers to catch those broadcasts, extract the data and use for UI updates.
So your saying that onProgessUpdate() isn't working? That seems weird because it should.
Another option that you have is just to make a Thread that loops.
The trick is that if you want to update the UI thread you will have to make a call to view.post() and give it a runnable that will actually perform the update. The idea here is that you must schedule an update on the UI thread, you can't just take it and say NOW!

Are there any real performance implications of Handlers vs Threads?

There have been a number of questions regarding the proper usage of Threads vs. Handlers vs. AsyncTask. (like here & here)
Those questions nicely addressed the question of when to use what. My question is more about the performance implications in certain types of cases.
As an example, I often see other people write code in which they use Threads simply to be able to schedule some code execution for the future. Whenever, I see this, I instinctively feel like refactoring the code to use a Handler and just a post a delayed runnable.
Here's an example where a Thread is used to update the seekbar for some media playing with a mediaplayer and then the way I would do it.
what I see a lot:
if (positionTracker != null && positionTracker.isAlive()
&& !positionTracker.isInterrupted()) {
return;
}
positionTracker = new Thread(new Runnable() {
public void run() {
int currentPosition = 0;
int total = player.getDuration();
while (player != null && CurrentPosition < total) {
try {
Thread.sleep(1000);
currentPosition = player.getCurrentPosition();
} catch (InterruptedException e) {
return;
} catch (Exception e) {
return;
}
if (someListener != null) {
someListener.onEvent();
}
}
}
}, "position tracker thread");
positionTracker.start();
And the way I like to do it:
Runnable trackPositionRunnable = new Runnable() {
#Override
public void run() {
currentPosition = player.getCurrentPosition();
if (someListener != null) {
someListener.onEvent();
mHandler.postDelayed(this, 1000);
}
}
};
mHandler.post(trackPositionRunnable);
Obviously, my preferred way is a bit easier to read and more concise. But what are the performance implications? Is one way method better, in terms of performance, than the other? If so, why?
Each method depends on what you plan on doing in that Runnable as to whether it will be useful or not. The biggest difference between them all is whether you plan on touching the UI or not. In Android you can't touch UI components off the UI thread (your example of media player is breaking this rule with raw Thread). Because of this rule that immediately divides what you can and can't do with each method. Performance differences between these methods is negligible because time spent running your background job is going to trump any differences between them.
Handler typically use another background thread to execute logic in, but it depends which thread constructed the Handler. If the Handler was constructed on the UI Thread (in response to callback onSomething) then your Runnable will run inside the UI Thread making it ok to touch UI Components. However, if you created it off the UI thread Runnables posted to it CANNOT touch UI components. The downside to Handlers created on the UI thread means you aren't doing these in the background so if a job takes a long time to run it will lock up the UI until its done. While Handlers run from non-UI threads will fix the any issue of locking up the UI. They take more work to setup and you still have to contend with how to safely update the UI in response to your background job (ie you still have to post another runnable back to the UI Thread if you want to update the UI).
Raw threads won't lock up the UI because they are running independently from the UI thread, but you can't touch UI components on them. That means you'll have to execute any code you want to update the UI with back on the UI thread which means more code needs to be written to get the UI thread to run it. This can be very complex. Raw threads should really be avoided because of the complexity in using them.
The most common example of background tasks is waiting for a response from the server. Most libraries block until the server sends a response which means you can't call them on the UI thread or else your user will be blocked from doing anything until the server returns a call. Not only will they be blocked, but the UI can't update itself to show a spinner or otherwise look alive. This is best to push off to a background thread. Technically Handlers and Threads can do this, but Handlers have to be constructed specially so they will use a true background thread.
This is where AsyncTask trumps Handlers because it does both true background jobs and UI updates. It has a section for doing some long running operation in the background and it has a section for updating the UI from the UI thread when its done. It even has an optional progress section so you can provide any intermediate progress to the UI while the task is running. The downside of an AsyncTask is that they must have an end. Background jobs that continue to run to periodically check if something has happened, sleep and check some more aren't conducive to the AsyncTask model. However, that's not to say you couldn't use a Handler to periodically kick off AsyncTask, but just for the completeness of the discussion I mention that.
In the end using raw Threads isn't all that easy or even "better" because Handlers can do pretty much anything that Threads can do with less code. But, Handlers are tricky in determining which thread the Runnable is executing on. Most often it's the UI thread, and technically setting it up to use a non-UI thread is tricky. Both options suffer from the UI update issues in that you have to do extra work to run UI jobs at the end of true background jobs. AsyncTask is really my preferred method for doing background jobs.
It is not Handler vs Threads. They are quite different things:
Thread: Is the old Java class that implements a thread of execution. As other parts of the Java APIs they are also available on Android. Notice than in late versions of the Java language they were superseeded by the Executors framework, so the recommended practice is to use Executor/Runnable, but due to it's simplicity Threads are still used sometimes.
Handler: This class is available only in Android, and it is mostly a mechanism to communicate with an existing Thread. You send the target thread Messages or Runnables, and you can also schedule this communication.
You usually need a Handler when you need to send something to a thread. This "something" can be, for instance, encapsulated data to be processed, or a Runnable to be executed in that thread. Every handler is usually associated to the current thread at the time of instantiation, unless you use a more exotic constructor. A typical use case is to schedule a repetitive task in the main thread (which is the UI thread). Notice that for scheduling a one-shot task there's an easiest way: Activity.runOnUithread.
Now for a background task that needs to be run in a thread different than the main one: in both approaches you'll have a thread running, but creating a handler means that Android will start a new Message Queue for that thread, which is something regular threads do not need to have, and because of this there will be some overhead. Thus if you need to start a thread that can run isolated without receiving information, i'd say the simple Thread is preferred. But if you need an execution queue to schedule Runnables you can choose between a Timer, an Executor, a "handled" thread, or even AlarmManager. The advantage of Handlers is that they can be attached to any already existing thread in your app, while Timer and Executors will internally launch a new dedicated thread when they are set up.
Correctness: Your first example is fraught with peril, since a MediaPlayer must be created on a thread with its own Looper and operations from any other thread may cause errors. Similarly, since your someListener.onEvent() is presumably updating a UI, it had better know to post to a handler on the UI thread anyway.
Performance: I have no measurements to offer, but in your example, the runtime cost is (thread switching) + (handler overhead), versus just (handler overhead). So for any thread switching overhead > 0, the threads are more expensive. On the other hand, if your entire application is coded in your favored style, and any piece of your code is slow and synchronous, you just made your application feel laggy.
Which is why anything potentially slow or synchronous needs to head toward the thread (or service) style, despite feeling more complex and error-prone. Your particular MediaPlayer example is not a perfect poster child for making this case.
If you're dealing with threads, I suggest that you use a handler together with it:
Handler handle = new Handler();
Thread new Thread()
{
#Override
public void run()
{
try
{
handle.postDelayed(new Runnable()
{
#Override
public void run()
{
"your code goes here"
}
},delay);
}
catch(Exception e)
{
e.printStackTrace();
}
};
}
That way you can delay the execution for as long as you want, or you can use post and Thread.sleep(delay), which I prefer these days.

Handler vs AsyncTask vs Thread [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I got slightly confused about the differences between Handlers, AsyncTask and Threads in Android. I've read quite a few blogs and questions here in StackOverflow.
Handler are background threads that provide you to communicate with the UI. Updating a progress bar, for instance, should be done via Handler. Using Handlers you have the advantage of MessagingQueues, so if you want to schedule messages or update multiple UI elements or have repeating tasks.
AsyncTask are similar, in fact, they make use of Handler, but doesn't run in the UI thread, so it's good for fetching data, for instance fetching web services. Later you can interact with the UI.
Thread however can't interact with the UI, provide more "basic" threading and you miss all the abstractions of AsyncTask.
However, I would like to have a socket connection run in service. Should this be run in a handler or a thread, or even an AsyncTask? UI interaction is not necessary at all. Does it make a difference in terms of performance which I use?
Meanwhile, the documentation has been majorly improved.
If we look at the source code, we will see AsyncTask and Handler is purely written in Java. (There are some exceptions, though. But that is not an important point)
So there is no magic in AsyncTask or Handler. These classes make our life easier as a developer.
For example: If Program A calls method A(), method A() could run in a different thread with Program A. We can easily verify by following code:
Thread t = Thread.currentThread();
int id = t.getId();
Why should we use a new thread for some tasks? You can google for it. Many many reasons,e.g: lifting heavily, long-running works.
So, what are the differences between Thread, AsyncTask, and Handler?
AsyncTask and Handler are written in Java (internally they use a Thread), so everything we can do with Handler or AsyncTask, we can achieve using a Thread too.
What can Handler and AsyncTask really help?
The most obvious reason is communication between the caller thread and the worker thread.
(Caller Thread: A thread which calls the Worker Thread to perform some tasks. A caller thread doesn't necessarily have to be the UI thread). Of course, we can communicate between two threads in other ways, but there are many disadvantages (and dangers) because of thread safety.
That is why we should use Handler and AsyncTask. These classes do most of the work for us, we only need to know which methods to override.
The difference between Handler and AsyncTask is: Use AsyncTask when Caller thread is a UI Thread.
This is what android document says:
AsyncTask enables proper and easy use of the UI thread. This class
allows to perform background operations and publish results on the UI
thread without having to manipulate threads and/or handlers
I want to emphasize two points:
1) Easy use of the UI thread (so, use when caller thread is UI Thread).
2) No need to manipulate handlers. (means: You can use Handler instead of AsyncTask, but AsyncTask is an easier option).
There are many things in this post I haven't said yet, for example: what is UI Thread, or why it's easier. You must know some methods behind each class and use it, you will completely understand the reason why.
#: when you read the Android document, you will see:
Handler allows you to send and process Message and Runnable objects
associated with a thread's MessageQueue
This description might seem strange at first. We only need to understand that each thread has each message queue (like a to-do list), and the thread will take each message and do it until the message queue is empty (just like we finish our work and go to bed). So, when Handler communicates, it just gives a message to caller thread and it will wait to process.
Complicated? Just remember that Handler can communicate with the caller thread safely.
As the Tutorial on Android background processing with Handlers, AsyncTask and Loaders on the Vogella site puts it:
The Handler class can be used to register to a thread and provides a simple channel to send data to this thread.
The AsyncTask class encapsulates the creation of a background process and the synchronization with the main thread. It also supports reporting progress of the running tasks.
And a Thread is basically the core element of multithreading which a developer can use with the following disadvantage:
If you use Java threads you have 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
And regarding the AsyncTask, as the Android Developer's Reference puts it:
AsyncTask enables proper and easy use of the UI thread. This class
allows to perform background operations and publish results on the UI
thread without having to manipulate threads and/or handlers.
AsyncTask is designed to be a helper class around Thread and Handler
and does not constitute a generic threading framework. AsyncTasks
should ideally be used for short operations (a few seconds at the
most.) 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 package such as Executor, ThreadPoolExecutor and
FutureTask.
Update May 2015: I found an excellent series of lectures covering this topic.
This is the Google Search: Douglas Schmidt lecture android concurrency and synchronisation
This is the video of the first lecture on YouTube
All this is part of the CS 282 (2013): Systems Programming for Android from the Vanderbilt University. Here's the YouTube Playlist
Douglas Schmidt seems to be an excellent lecturer
Important: If you are at a point where you are considering to use AsyncTask to solve your threading issues, you should first check out ReactiveX/RxAndroid for a possibly more appropriate programming pattern. A very good resource for getting an overview is Learning RxJava 2 for Android by example.
After looking in-depth, it's straight forward.
AsyncTask:
It's a simple way to use a thread without knowing anything about the java thread model.
AsyncTask gives various callbacks respective to the worker thread and main thread.
Use for small waiting operations like the following:
Fetching some data from web services and display over the layout.
Database query.
When you realize that running operation will never, ever be nested.
Handler:
When we install an application in android, then it creates a thread for that application called MAIN UI Thread. All activities run inside that thread. By the android single thread model rule, we can not access UI elements (bitmap, textview, etc..) directly for another thread defined inside that activity.
A Handler allows you to communicate back with the UI thread from other background threads. This is useful in android as android doesn’t allow other threads to communicate directly with UI thread. A handler can send and process Message and Runnable objects associated with a thread’s MessageQueue. Each Handler instance is associated with a single thread and that thread’s message queue. When a new Handler is created, it is bound to the thread/message queue of the thread that is creating it.
It's the best fit for:
It allows you to do message queuing.
Message scheduling.
Thread:
Now it's time to talk about the thread.
Thread is the parent of both AsyncTask and Handler. They both internally use thread, which means you can also create your own thread model like AsyncTask and Handler, but that requires a good knowledge of Java's Multi-Threading Implementation.
An AsyncTask is used to do some background computation and publish the result to the UI thread (with optional progress updates). Since you're not concerned with UI, then a Handler or Thread seems more appropriate.
You can spawn a background Thread and pass messages back to your main thread by using the Handler's post method.
Thread
Android supports standard Java Threads. You can use standard Threads and the tools from the package “java.util.concurrent” to put actions into the background. The only limitation is that you cannot directly update the UI from the a background process.
If you need to update the UI from a background task you need to use some Android specific classes. You can use the class “android.os.Handler” for this or the class “AsyncTask”
Handler
The class “Handler” can update the UI. A handle provides methods for receiving messages and for runnables. To use a handler you have to subclass it and override handleMessage() to process messages. To process Runable, you can use the method post(); You only need one instance of a handler in your activity.
You thread can post messages via the method sendMessage(Message msg) or sendEmptyMessage.
AsyncTask
If you have an Activity which needs to download content or perform operations that can be done in the background AsyncTask allows you to maintain a responsive user interface and publish progress for those operations to the user.
For more information you can have a look at these links.
http://mobisys.in/blog/2012/01/android-threads-handlers-and-asynctask-tutorial/
http://www.slideshare.net/HoangNgoBuu/android-thread-handler-and-asynctask
Thread:
You can use the new Thread for long-running background tasks without impacting UI Thread. From java Thread, you can't update UI Thread.
Since normal Thread is not much useful for Android architecture, helper classes for threading have been introduced.
You can find answers to your queries in Threading performance documentation page.
Handler:
A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue.
There are two main uses for a Handler:
To schedule messages and runnables to be executed as some point in the future;
To enqueue an action to be performed on a different thread than your own.
AsyncTask:
AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
Drawbacks:
By default, an app pushes all of the AsyncTask objects it creates into a single thread. Therefore, they execute in serial fashion, and—as with the main thread—an especially long work packet can block the queue. Due to this reason, use AsyncTask to handle work items shorter than 5ms in duration.
AsyncTask objects are also the most common offenders for implicit-reference issues. AsyncTask objects present risks related to explicit references, as well.
HandlerThread:
You may need a more traditional approach to executing a block of work on a long-running thread (unlike AsyncTask, which should be used for 5ms workload), and some ability to manage that workflow manually. A handler thread is effectively a long-running thread that grabs work from a queue and operates on it.
ThreadPoolExecutor:
This class manages the creation of a group of threads, sets their priorities, and manages how work is distributed among those threads. As workload increases or decreases, the class spins up or destroys more threads to adjust to the workload.
If the workload is more and single HandlerThread is not suffice, you can go for ThreadPoolExecutor
However I would like to have a socket connection run in service. Should this be run in a handler or a thread, or even an AsyncTask? UI interaction is not necessary at all. Does it make a difference in terms of performance which I use?
Since UI interaction is not required, you may not go for AsyncTask. Normal threads are not much useful and hence HandlerThread is the best option. Since you have to maintain socket connection, Handler on the main thread is not useful at all. Create a HandlerThread and get a Handler from the looper of HandlerThread.
HandlerThread handlerThread = new HandlerThread("SocketOperation");
handlerThread.start();
Handler requestHandler = new Handler(handlerThread.getLooper());
requestHandler.post(myRunnable); // where myRunnable is your Runnable object.
If you want to communicate back to UI thread, you can use one more Handler to process response.
final Handler responseHandler = new Handler(Looper.getMainLooper()) {
#Override
public void handleMessage(Message msg) {
//txtView.setText((String) msg.obj);
Toast.makeText(MainActivity.this,
"Foreground task is completed:"+(String)msg.obj,
Toast.LENGTH_LONG)
.show();
}
};
in your Runnable, you can add
responseHandler.sendMessage(msg);
More details about implementation can be found here:
Android: Toast in a thread
In my opinion threads aren't the most efficient way of doing socket connections but they do provide the most functionality in terms of running threads. I say that because from experience, running threads for a long time causes devices to be very hot and resource intensive. Even a simple while(true) will heat a phone in minutes. If you say that UI interaction is not important, perhaps an AsyncTask is good because they are designed for long-term processes. This is just my opinion on it.
UPDATE
Please disregard my above answer! I answered this question back in 2011 when I was far less experienced in Android than I am now. My answer above is misleading and is considered wrong. I'm leaving it there because many people commented on it below correcting me, and I've learned my lesson.
There are far better other answers on this thread, but I will at least give me more proper answer. There is nothing wrong with using a regular Java Thread; however, you should really be careful about how you implement it because doing it wrong can be very processor intensive (most notable symptom can be your device heating up). AsyncTasks are pretty ideal for most tasks that you want to run in the background (common examples are disk I/O, network calls, and database calls). However, AsyncTasks shouldn't be used for particularly long processes that may need to continue after the user has closed your app or put their device to standby. I would say for most cases, anything that doesn't belong in the UI thread, can be taken care of in an AsyncTask.
AsyncTask is designed to perform not more than few seconds operation to be done in background (not recommended for megabytes of file downloading from server or compute cpu intensive task such as file IO operations ). If you need to execute a long running operation, you have been strongly advised to use java native threads. Java gives you various thread related classes to do what you need. Use Handler to update the UI Thread.
public class RequestHandler {
public String sendPostRequest(String requestURL,
HashMap<String, String> postDataParams) {
URL url;
StringBuilder sb = new StringBuilder();
try {
url = new URL(requestURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(getPostDataString(postDataParams));
writer.flush();
writer.close();
os.close();
int responseCode = conn.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
sb = new StringBuilder();
String response;
while ((response = br.readLine()) != null){
sb.append(response);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder();
boolean first = true;
for (Map.Entry<String, String> entry : params.entrySet()) {
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
return result.toString();
}
}
It depends which one to chose is based on the requirement
Handler is mostly used to switch from other thread to main thread, Handler is attached to a looper on which it post its runnable task in queue.
So If you are already in other thread and switch to main thread then you need handle instead of async task or other thread
If Handler created in other than main thread which is not a looper is will not give error as handle is created the thread, that thread need to be made a lopper
AsyncTask is used to execute code for few seconds which run on background thread and gives its result to main thread
** *AsyncTask Limitations
1. Async Task is not attached to life cycle of activity and it keeps run even if its activity destroyed whereas loader doesn't have this limitation
2. All Async Tasks share the same background thread for execution which also impact the app performance
Thread is used in app for background work also but it doesn't have any call back on main thread.
If requirement suits some threads instead of one thread and which need to give task many times then thread pool executor is better option.Eg Requirement of Image loading from multiple url like glide.
Let me try and answer the question here with an example :) - MyImageSearch [Kindly refer the image here of the main activity screen - containing an edit text / search button / grid view]
Description of MyImageSearch - Once user enters the details on the edit text field and clicks on the search button, we will search images on the internet via the web services provided by flickr (you only need to register there to get a key/secret token) - for searching we send an HTTP Request and GET JSON Data back in response containing the url's of individual images which we will then use to load the grid view.
My Implementation - In the main activity I will define a inner class which extends the AsyncTask to send the HTTP Request in doInBackGround Method and fetch the JSON Response and update my local ArrayList of FlickrItems which I am going to use to update my GridView via the FlickrAdapter (extends the BaseAdapter) and call the adapter.notifyDataSetChanged() in the onPostExecute() of AsyncTask to reload the grid view. Note that here the HTTP Request is a blocking call because of which I have done it via the AsyncTask. And, I can cache the items in adapter to increase the performance or store them on SDCard. The grid that I will be inflating in the FlickrAdapter contains in my implementation a progressbar and image view. Below you can find the code for mainActivity which I used.
Answer to the Question Now -
So once we have the JSON data for fetching individual Images we can implement the logic of getting the images in background via Handlers or Threads or AsyncTask. We should note here that since my images once downloaded must be displayed on the UI/main thread we cannot simply use threads as it is since they don't have access to the context.
In the FlickrAdapter, the choices I could think of:
Choice 1: Create a LooperThread [extends thread] - and keep on
downloading images sequentially in one thread by keeping this thread
open [looper.loop()]
Choice 2: Make use of a Thread Pool and post the runnable via myHandler which
contains reference to my ImageView, but since the views in Grid View
are recycled, again the problem might arise where image at index 4 is
displayed at index 9 [download may take more time]
Choice 3 [I used this]: Make use of a Thread Pool and send a message to myHandler, which contains data related to ImageView's index and
ImageView itself, so while doing handleMessage() we will update the
ImageView only if currentIndex matches the index of the Image we
tried to download.
Choice 4: Make use of AsyncTask to download the
images in background, but here I will not have access to the number of threads I want in
the thread pool and it varies with different android version, but in Choice 3 I can make of conscious decision of the size of thread pool depending on device configuration being used.
Here the source code:
public class MainActivity extends ActionBarActivity {
GridView imageGridView;
ArrayList<FlickrItem> items = new ArrayList<FlickrItem>();
FlickrAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageGridView = (GridView) findViewById(R.id.gridView1);
adapter = new FlickrAdapter(this, items);
imageGridView.setAdapter(adapter);
}
// To avoid a memory leak on configuration change making it a inner class
class FlickrDownloader extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
FlickrGetter getter = new FlickrGetter();
ArrayList<FlickrItem> newItems = getter.fetchItems();
// clear the existing array
items.clear();
// add the new items to the array
items.addAll(newItems);
// is this correct ? - Wrong rebuilding the list view and should not be done in background
//adapter.notifyDataSetChanged();
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
adapter.notifyDataSetChanged();
}
}
public void search(View view) {
// get the flickr data
FlickrDownloader downloader = new FlickrDownloader();
downloader.execute();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
I hope my answer though long will help in understanding some of the finer details.
Thread
When you start an app, a process is created to execute the code. To efficiently use computing resource, threads can be started within the process so that multiple tasks can be executed at the time. So threads allow you to build efficient apps by utilizing cpu efficiently without idle time.
In Android, all components execute on a single called main thread. Android system queue tasks and execute them one by one on the main thread. When long running tasks are executed, app become unresponsive.
To prevent this, you can create worker threads and run background or long running tasks.
Handler
Since android uses single thread model, UI components are created non-thread safe meaning only the thread it created should access them that means UI component should be updated on main thread only. As UI component run on the main thread, tasks which run on worker threads can not modify UI components. This is where Handler comes into picture. Handler with the help of Looper can connect to new thread or existing thread and run code it contains on the connected thread.
Handler makes it possible for inter thread communication. Using Handler, background thread can send results to it and the handler which is connected to main thread can update the UI components on the main thread.
AsyncTask
AsyncTask provided by android uses both thread and handler to make running simple tasks in the background and updating results from background thread to main thread easy.
Please see android thread, handler, asynctask and thread pools for examples.
Handler - is communication medium between threads. In android it is mostly used to communicate with main thread by creating and sending messages through handler
AsyncTask - is used to perform long running applications in a background thread. With nAsyncTask you get can do the operation in a background thread and get the result in the main thread of the application.
Thread - is a light weight process, to achieve concurrency and maximum cpu utilization. In android you can use thread to perform activities which does not touch UI of the app

Categories

Resources