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
Related
AsyncTask is a standard way to perform long running operations asynchronously on a background thread without holding up the UI thread. One should not perform any UI interactions from the doInBackground() method.
My question: What are examples of UI interactions that are forbidden? Would it be any of the following:
LayoutInflater.inflate()
View.findViewById()
TextView.setText()
I'm inclined to say yes, but we have some code right now that does all of these (and more) and is called from the doInBackground() method, and yet the code is working. I've seen other people indicate they receive an exception when attempting to perform UI activity from doInBackground(), but that is not our experience.
Our code is generating an on-screen report that is not visible until the entire operation is complete. On rare occasion (hard to reproduce) when attempting to cancel the operation very quickly, we will see the application get into a weird state, but it doesn't crash.
Before changing our code in hopes of finding this rare condition, I wanted to see if anyone had some thoughts on why our code is "working" as-is.
The only other tidbit of information that might be helpful is that our doInBackground method has the following code template:
protected Boolean doInBackground(Void... voids) {
if (null == Looper.myLooper()) {
Looper.prepare();
}
publishProgress(0.0);
// Perform ui/non-ui logic here
Looper myLooper = Looper.myLooper();
if (null != myLooper && Looper.getMainLooper() != myLooper) {
myLooper.quit();
}
return true;
}
The Looper is needed for some of the report generating code (omitted) that uses a new Handler() to generate data. I'm not sure if creating the Looper is somehow making our ui interactions legal.
(I do have a stack trace that clearly shows our UI activity being called from doInBackground, in case you thought we might be spinning off some separate threads to update our UI)
AsyncTask is not meant for really long running work, it should complete within a few seconds. It is a one-shot completely managed thread context, which should not have its own Looper attached to it. That actually will break the backing AsyncTask functionality - starving off other future AsyncTask operations you may be starting. If you have something which requires a Looper, you should be using your own Thread or ThreadPool rather than an AsyncTask. You'll also want to make sure you retain a reference to your AsyncTask so it can be cancelled appropriately - this is a source of many memory leaks and/or exceptions due to invalid state when onPostExecute() is called.
The intent of the publishProgress() method is to give your app the ability to get updates it can reflect on the UX. You are correct, setText(), etc. should not be run in the doInBackground() callback. That callback is executed in arbitrary thread context in which you do not control and cannot make UI updates.
You may be able to use inflateLayout() and findViewById(), but this is not a good practice to do this outside of initialization as these are potentially expensive operations. Inflation has to parse the binary layout and create view objects on the fly. Finding by ID walks the entire view hierarchy to find the component you desire. A better practice would be to cache these at creation (for an Activity or Fragment) or when creating a view as part of an adapter (such as a ViewHolder in RecyclerView.
When I need something to run asynchronously, such as a long running task or a logic that uses the network, or for whatever reason,
Starting a new Thread and running it works fine.
Creating a Handler and running it works as well.
What's the difference? When should I use each one?
What are the advantages / reasons to use a Handler and not a Thread?
PS.
- For this question's sake, let's ignore AsyncTask.
- Handler().postDelayed use case is clear to me, for this question's sake let's assume I need the task to start immediately.
If whatever you are doing is "heavy" you should be doing it in a Thread. If you do not explicitly start it in its own thread, then it will run on the main (UI) thread which may be noticeable as jittery or slow to respond interface by your users.
Interestingly when you are using a thread it is often useful to also use a Handler as a means of communication between the work thread that you are starting and the main thread.
A typical Thread/Handler interaction might look something like this:
Handler h = new Handler(){
#Override
public void handleMessage(Message msg){
if(msg.what == 0){
updateUI();
}else{
showErrorDialog();
}
}
};
Thread t = new Thread() {
#Override
public void run(){
doSomeWork();
if(succeed){
//we can't update the UI from here so we'll signal our handler and it will do it for us.
h.sendEmptyMessage(0);
}else{
h.sendEmptyMessage(1);
}
}
};
In general though, the take home is that you should use a Thread any time you are doing some work that could be long running or very intensive (i.e. anything network, file IO, heavy arithmatic, etc).
Handler and Thread are really 2 different things.
A thread must be created to execute long running jobs.
A Handler is very convenient object to communicate between 2 threads (for instance : a background thread need to update the UI. You can use a Handler to post some Runnable from your background thread to the UI thread).
So you don't have the choice between Handler or Thread. Use a thread to do heavy jobs! (you can use a Handler if your background thread will trigger some job to be done in another thread - most of the time the UI thread)
Handler and Thread are two different things, but they do not contradict each other. You can have a Handler and a Thread at the same time and actually each Handler must be running in a Thread.
For more details, you may want to check out this article.
A Handler runs on the same Thread, a Thread runs on a different thread.
Use a Handler if you need to run something on the same thread, usually a GUI element or something like that.
Use a Thread if you want to keep the main thread free to do other things. Use this for anything that takes a significant amount of time.
Handlers are the best way of communication between the background and UI thread. Generally Handlers are associated with message Queue of a Thread and they are used to send messages and runnable to the Message.
USE:
Thread: To do tasks in saperate(Background) thread than UI thread. (helps to unblock the UI thread)
Handler Used to communicate between the UI and Background thread.
Have a look at this article
If you need to update the user interface from a new Thread, you need
to synchronize with the user interface thread.
You can use the android.os.Handler class or the AsyncTasks class for
this.
The Handler class can update the user interface. A Handler provides
methods for receiving instances of the Message or Runnable class.
You thread can post messages via the sendMessage(Message msg) method
or via the sendEmptyMessage() method.
... more info here about threads etc. (includes turorials for the different threading and sync mechanisms and when to use what)
What are the advantages / reasons to use a Handler and not a Thread?
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.
When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the 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.
If you use java threads, you have to handle somethings on your own - synchronizing with main thread, cancelling a thread etc.
This single Thread does not create a thread pool unless you use ThreadPoolExecutor or ExecutorService API.
(Taken this query from your comments on Blackbelt answer)
Why not use an Executor? and even if I did want to use a Handler to do that, how?
Reference : Thread Performance article
There are certain types of work that can be reduced to highly parallel, distributed tasks. With the sheer volume of work packets this creates, AsyncTask and HandlerThread aren’t appropriate classes. The single-threaded nature of AsyncTask would turn all the threadpooled work into a linear system. Using the HandlerThread class, on the other hand, would require the programmer to manually manage load balancing between a group of threads.
ThreadPoolExecutor is a helper class to make this process easier. 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.
BlockingQueue workQueue= new LinkedBlockingQueue<Runnable>(100); // Work pool size
ThreadPoolExecutor executor = new ThreadPoolExecutor(
Runtime.getRuntime().availableProcessors(), // Initial pool size
Runtime.getRuntime().availableProcessors(), // Max pool size
1, // KEEP_ALIVE_TIME
TimeUnit.SECONDS, // KEEP_ALIVE_TIME_UNIT
workQueue);
You can refer to this developer guide article on create-threadpool for more details.
Have a look at this post for usage of Handler to run multiple Runnable instances. In this case, all Runnable tasks will run in a single Thread.
Android: Toast in a thread
Handler can be used in conjunction with Thread in order to create a Queued mechanism. Uou can use the handler to post something on the Thread Looper
If you have to execute a task only once separately outside main thread, then use Thread. If you want to execute tasks repeatedly then android provides a way to keep threads alive and receive the messages or Runnable objects to process them using Looper in a MessageQueue.
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!
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.
I have many tasks,and I should use Multi-thread to process them ,what's the best solution,?the mean is I can use The least number of threads but process the most task With the fastest time.
I think AsyncTask is useful for you. You can find more about it Android - AsyncTask in this nice explanation and example given.
And if you want to use Thread then you have to manage all the threads, and also be sure about not to blocking the UI Thread.
Difference between Handler and AsyncTask...
1.The Handler is associated with the application's main thread. it handles and schedules
messages and runnables sent from background threads to the app main thread.
2.AsyncTask provides a simple method to handle background threads in order to update the UI without blocking it by time consuming operations.
The answer is that both can be used to update the UI from background threads, the difference would be in your execution scenario. You may consider using handler it you want to post delayed messages or send messages to the MessageQueue in a specific order.
You may consider using AsyncTask if you want to exchange parameters (thus updating UI) between the app main thread and background thread in an easy convinient way.
Example for Threads, Handlers and AsyncTask in Android.
Thanks.
Please look at services and AsyncTask for thee same. It is better than dealing with pure threads unless you are in NDK and working with pthreads.
A good post on multi-threading in Android can be found here:
http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html
There is many way to do multiThreading in android.
I like to use handlerThread which give you all the tools to lets your UI communicate eeasily with your threads.
For example :
public class MyThread extends HandlerThread implements Callback
{
public MyThread()
{
super(ThreadDP.class.getSimpleName(), Process.THREAD_PRIORITY_DISPLAY);
this.start();
}
#Override
protected void onLooperPrepared()
{
super.onLooperPrepared();
}
#Override
public boolean handleMessage(Message msg) {
switch (msg.what)
{
case 1 :
this.doA();
return true;
//Message 2 let's call doB()
case 2 :
this.doB();
return true;
default:
return false;
}
}
//Implement doA() and doB()
}
This simple thread can handle message sent by your activity or other threads. The handle system is pretty fast (i can get a 25fps mjpeg without any problem).
There is probably better solution (i'm not an expert) but i can get up to 5 simultaneous thread receiving , sending (and processing) data on network working like a charm.