I'm learning Android, and I have few problems understanding Threads-Handlers.
I saw examples where you declare a handler in working Thread that works with Looper of mainThread- it's clear to me.
Also I saw examples where you create a working Thread and declare your own Looper, like this:
public void run() {
Looper.prepare();
handler = new Handler();
Looper.loop();
}
I understand it creates a thread with with own Looper and a private message queue but what is the purpose of this and why use it?
Is it a message queue that can work on the application UI like mainThread can? is it a speed issue of working on UI faster then mainThread?
And one more thing...I saw a class HandlerThread, if I understand it right, It's the same as creating a new Thread and setting to it new Looper like I showed in the example above? If not I'm interested to know what is the difference and where to use it?
There could be plenty of reasons why to do that. For example, if processing a message takes a significant amount of time you may want to do it on another thread to prevent the UI thread from freezing. It wouldn't be able to directly manipulate the UI thread, but you could always do a runOnUiThread to pass messages back to the UI thread.
HandlerThread basically does exactly what's above. It encapsulates the weird calls you need to do to make a looper, but it makes you use some odd looking code to make the actual handler for that thread. Nothing wrong with using it, but it won't save you much effort.
Related
I read a lot about threads but don't understand yet :( let me explain to you what I have learned about threads. all we are working on such as codes any thing worked on UI thread or Main thread right? After that what happens if we call runOnUiThread? and my other question how do we know it's Time to use a new thread? I mean how do we understand we are working on another thread or replace or code in the new thread?
I know this is an unclear question but I don't understand as well. Please help me Thanks, john.
Let me try to answer. Actually Android has Main Thread (also called as UI Thread) and other thread.
Main Thread is basically for showing UI and other thread is for processing other big processes such as connecting to the server, etc.
runOnUiThread is called when you want to move from other thread to main thread. It is needed since only main thread can show/display result on UI. So when you have done some process on other thread, and you want to display the result on the apps, you need to show it on main thread by calling runOnUiThread.
We working on other thread only if it is a big or lengthy process like taking data from the server, load data, etc. And we move from other thread to main thread whenever we want to show some UI result.
Easiest way is to use AsyncTask<> class. You'll need to override three functions.
doInBackGround(...) : The codes that gets executed in background thread.
onPreExecute(..) : code that gets executed before background thread
completes executing like displaying progress bars, etc.
onPostExecute(...): Code that gets executed after background thread
has completed running. Perform task like updating UI in here
One general rule of thumb is: Don't use multithreading if you don't need to. Multithreading is always error-prone, and in many situations there's no benefit. Basically, you start a new thread whenever you execute a lengthy operation (i.e. some extensive computation like image processing) that would block the main thread for some time, so the application would become unresponsive.
This should be a quick one...
I have taken over development of a project from someone else and it seems to me that they haven't got a clue what they were doing. I have found numerous examples of bad code practices and logical errors that I'm sure would make your blood boil as much as mine. I am now dealing with an area of code in which they have for some unknown reason decided to create an absurd amount of message handlers. I think they don't understand what a handler is for... I have one class which contains as much as 4 handlers as class fields all created by the same thread! One of those handlers looks like this:
private Handler messageHandler1 = new Handler() {
public void handleMessage(final Message msg) {
super.handleMessage(msg);
new Thread() { // why are we starting a thread in the root of a message handler?!
public void run() {
super.run();
// some code...
}
}.start();
}
};
Besides the useless variable name, I'm more concerned by the creation of a new thread right at the root of the handler. My understanding of handlers is that they are used to allow you run code on another thread, so one thread can use the handler of another thread to be able to run code on that other thread... So then, surely it is totally pointless to use a handler in the first place if you're just going to create a new thread straight away?! I just wanted someone with a bit more wisdom to confirm that (or not) before I remove this handler and do it (what I believe to be) the right way.
Thanks
A Handler is always pointing toward a Thread.
When the Handler receives a Message the best practice is that Handler handles a message on its own Thread. That is the whole point of creating a Handler in the first place.
Starting a new Thread from a within Handler.handleMessage() is a weird choice at best.
I'm developing an Android network application. I want to have one worker thread that will handle all incoming data over a socket). The thread will be active all the time.
I can start the thread from one of my activities, but how to handle it after the activity is changed?
By handle, I mean how to interact with the thread (passing data from thread to current UI or sending data to the thread from the current UI).
I'm looking at AsyncTask but I'm not sure if it can be used with my situation
I think you want to look at one of two models.
The first is to use a Service which will "own" the socket connection. The second is to spin up a HandlerThread to "own" the connection. Which you choose is based on what the socket is doing.
If the socket connection contains data that you need to receive, typically stuff you'll cache locally, then a Service is more appropriate, because running in a Service means that your work will get done eventually. On the other hand if you are doing something like downloading an image that is only ever displayed in your UI, then using a raw HandlerThread might be the right choice. The reasoning here is that the moment your UI goes away your socket connection might as well be closed. Put another way, the choice is based on how ephemeral the use of the data is.
Now, if you're going to use a Service, please, please, use an IntentService which will handle the grotesque details of shutting down the Service at the appropriate time. It will also put your processing code on the correct Thread. A command sent to a Service by default runs on the main/UI thread of your application. An IntentService marshals the work to a background thread.
If you're going to use a HandlerThread, I would make a class that extends HandlerThread and then use the singleton pattern to handle accessing the same HandlerThread from any Activity.
One important question to ask yourself though is when your Service or HandlerThread shuts down. When is the work done and how is this signaled? Is it just when no more data arrives? When your apps UI goes into the background?
For this requirement I suggest that you create and use JAX-WS or JAX-RS.Here are a lot of examples which fully describe that. In that case you can use AsyncTask easily. Look at this answer, I suppose that this solution can meet your needs.
I would go with this:
Handler mHandler = new Handler();
Thread t = new Thread(new Runnable(
#Override
public void run () {
while (true /* or your breaking condition */) {
//Here you put your socket algorithm
mHandler.post(new Runnable() {
#Override
public void run () {
//Here you put every change you want to do on UI thread
}
}
//This is necessary to reduce process consumption
try {
Thread.sleep(30L);
} catch (Exception e) {
e.printStackTrace();
}
}
}));
t.start();
How to know on which UI
Each handler you create is attached to the class on which it was created.
As you can see here Android | Handler
For example, if you have a class that extends Activity and you create a Handler there, it'll work on that UI thread.
I am having a problem understanding the differences between some kinds of making a tread loop.
one is (a rough demonstration):
Thread thread=new Thread("name") {
public void run()
{
// do stuff
}
}.start();
the second is:
making a class that imlpements runnable,
creating a thread :
Thread thread = new Thread(this,"name").start();
and the third (in android, i don't if it can work some how else):
making a Handler,
creating a Runnable,
and having handler.postDelayed(runnable), or handler.post(runnable).
I don't understand what's the difference, the only thing i did notice is that making a Thread makes the run loop work a lot faster than using a handler.
could some one explain to me what's the difference between them and what should i use to what?
The first and the second way are exactly the same. It is just different constructions that can be more useful in different situations. Note that Thread implements Runnable and may just run himself in the new thread.
The third way is a little bit misinterpreted by you. Handler runs Runnable in the thread where the Handler was instantiated (unless you specify another looper). If you created your Handler in the UI thread it will run Runnable in the UI thread as well. And as a result it may work slower.
In my activity, my app downloads a list of something from a website via an Http Connection. Before this list of things is displayed on the screen, I have a Loading... TextView with a little spinning ProgressBar to indicate that the data is currnetly being downloaded.
I noticed, that if I do any type of Thread.sleep() during the process of fetching the data from the web, it freezes the spinning ProgressBar.
Even if I put the method in it's own Handler Runnable so that it's on it's own thread, the animation freezing still occurs.
Is there anything I can do about this?
Yes, use AsyncTask.
A Handler is usually attached to the UI thread. Posting Runnables to it doesn't change the fact that they will run on the UI thread.
Any application should do long running tasks on a seperate thread to the UI thread as any blocking calls will not allow the UI to update.
As the other poster said, using Runnables alone do not mean the code will be executed on a seperate thread. In this case the run() method will execute on whatever thread your Handler object was created on. Either subclass Thread or pass your runnabe to new thread object with public Thread (Runnable runnable).
Using AsyncTasks, Loaders or Threads will help.
Also read Designing for Responsiveness and Multithreading For Performance. Following the above approaches will help you avoid ANRs
The reason for such a behaviour is that:
When you do thread.sleep() inside a runnable, it is the UI thread which executes that runnable rather than the respective other thread which you created. Basically what happens is that when you post any runnable through the handler of the UI thread, UI thread will poll from its queue and execute the runnable; in this case the runnable will do sleep.
Hence no change in progress bar