I have a Handler, mHandler, tied to the main thread. mHandler resides in a Service. Say I now post a Runnable to mHandler from the main thread like so:
public class SomeService extends Service {
// Handler is created on the main thread
// (and hence it is tied to the main thread)
private Handler mHandler = new Handler();
#Override
public void onDestroy() {
// onDestroy runs on the main thread
// Is the code in this Runnable processed right away?
mHandler.post(new Runnable() {
// (Some code statements that are to be run on the main thread)
...
});
super.onDestroy();
}
}
I know the example is a little silly as the Handler is unnecessary. However, it is a good example for this question.
Now my questions are:
Will the code statements in the Runnable be processed right away as the thread that posts the Runnable is also the thread that is to process the Runnable? Or does it work differently as the Handler internally uses a MessageQueue and hence there might be Runnables posted to the Handler elsewhere (which arrive before my Runnable)?
Moreover, is it possible that the statements will never run as the post(Runnable r) is an async call and hence onDestroy() will finish and the Service will be killed by the system before the Handler gets to run the code.
Thank you in advance.
Since a Service does not imply a separate thread, your runnable will be posted at the end of the main Looper's queue, so yes, there may be messages/runnables scheduled before yours.
Again, since Service does not imply a distinct thread, a call to onDestroy does not mean that the Handler's thread has been terminated. In this example, you are posting to the main looper, and that thread is active until the application process terminates.
Related
I know a handler is bound to the thread's message queue in which it is created, but what if i create a handler in a service and posting a runnable declared in activity to which my service is bound.
For example:
In service:-
Handler handler=new Handler();
handler.post(Mainactivity.runnable);
In activity inside oncreate method:-
Runnable runnable=new Runnable(){
public void run{
//some code here
}
};
Can someone please explain me what's happening here?
Please find information about Message Queue and Looper in below link
Understanding Android Core: Looper, Handler, and HandlerThread
In the Android via Looper, Handler, and HandlerThread. The System can be visualized to be a vehicle as in the article’s cover.
1.MessageQueue is a queue that has tasks called messages which should be processed.
2.Handler enqueues task in the MessageQueue using Looper and also executes them when the task comes out of the MessageQueue.
3.Looper is a worker that keeps a thread alive, loops through MessageQueue and sends messages to the corresponding handler to process.
4 Finally Thread gets terminated by calling Looper’s quit() method.
By default service will run on UI Thread. So the handler you create on service will post the runnable on UI Thread
since several days, I tried to figure out what exactly happens if I execute code in
void function(){
//somePreExecutionCode
new Handler().post(new Runnable(){
#Override
public void run(){
//someCode
}
});
}
It seems like it isn't blocking the UI, so buttons, which calls function() doesn't stuck in the clicked position until someCode has finished.
But if somePreExecutionCode starts a progressBar, the progressBar is shown at exactly the same moment, when someCode has finished.
I know, there are AsyncTasks for, but is there any other possibility?
And whats the difference between
new Handler().post
and
View.post
?
When an Android application is created, system creates a main thread of execution. This thread is referred to as UI thread and all UI related operations happen on this thread in order to avoid synchronization issues.
A Looper instance is created on this thread, which has a MessageQueue data structure. The Looper will be in an infinite loop waiting to read the Message / Runnable instances posted on the MessageQueue. To add Message7 / Runnable to the MessageQueue, Handler is used.
When you create a Handler instance, it will be associated with the current thread of execution and the Looper instance created on that particular thread.
Hence when you post a message via a Handler, the Message is added to the MessageQueue, which will be read in FIFO order by Looper and will be delivered to the target.
new Handler().post() and View.post are bit different.
When you post Messages via View.post, you are guaranteed the Message will be posted on UI thread's MessageQueue, since it internally uses Handler instance created on UI Thread.
If you create Handler instance on UI thread and post the Message using it on any thread, Message will be posted to the UI thread's MessageQueue.
If you create Handler instance on a non-UI thread and post Messages using it, they will be posted on non-UI thread's MessageQueue.
Putting it simply, there are Looper threads, for example, UI thread. Such thread has its own Looper, which runs a message loop for the thread.
Such thread, typically, has a Handler, which processes its Looper's messages - overriding public void handleMessage(Message msg) or executing a Runnable, which was posted to it's looper's message queue.
When you're creating a Handler in the context of UI thread (like you did in your code), it gets associated with UI thread's looper, so your \\someCode runs on UI thread.
I guess, in your use case new Handler().post(Runnable) and View:post(Runnable) are mostly the same, as they both add a Runnable to the UI thread message queue.
But they are not the same.
View:post(Runnable) will add a Runnable to the UI thread looper's message queue;
Handler:post(Runnable) will add a Runnable to its associated thread looper's message queue
My explanation is pretty much intuitive, so correct me anyone if I am wrong.
According to the Android View's documentation:
The Runnable will be run on the user interface thread
According to the Android Handler's documentation:
The Runnable will be run on the thread to which this handler is attached
So, in the Handler's case, you can create it in any thread you want, it's a kind of anchor that will execute the Runnable you provide in the thread it was created in.
In the View.post, you will always execute the Runnable in the uI thread.
I had to add Looper to the following code:
public class MyRunnable implements Runnable
{
#Override
public void run()
{
Looper.prepare();
final Looper looper = Looper.myLooper();
new Handler().postDelayed(
new Runnable()
{
#Override
public void run()
{
try
{
}
catch (Exception ex)
{
}
finally
{
looper.quit();
}
}
}, 100);
Looper.loop();
}
}
Notice that I have a runnable inside a runnable. The nested runnable gets executed through a Handler. Initially I didn't have Looper but Android complained that I needed to call Looper.prepare before executing another thread.
I read up on Looper but it still seems kind of cryptic. It seems to act like some kind of internal messaging pipeline. It isn't clear to me why this is necessary since there are no messages going from my outer runnable to my inner runnable. Even though that is true, it seems that Android just makes the hard rule that if you call a thread from a thread, you MUST also call Looper.prepare. Even if I accept that as-is, it still doesn't help to understand why I need to call looper.loop and looper.quit. If I omit Looper.loop, my Handler never runs and that is what isn't clear. What does Looper.loop do that allows my Handler to run?
Here is a great article about that.
Looper and Handler in Android
It comes along with a simple schema that leads to straight understanding of relationship between Loopers and Handler.
On this schema, we see that, within the same thread (depicted by the big rectangle), no matter how many handler you create, they will all be using the same Looper, i.e., the unique looper of this thread.
Note:
Looper have to be prepared to allow associated handler to process posted messages.
Android application, more precisely, android app UI thread(the main thread), already comes with a prepared looper (the mainLooper).
Here is how to Communicating with the UI Thread.
A simple concept of the looper:
Every worker thread you create and run ends once it performs its last operation.
To prevent your thread termination you can start a loop by calling Looper.loop(), think of it as while(true){} statement. Before calling Looper.loop() you have to prepare the loop with Looper.prepare(), if it is not prepared yet.
To terminate the loop and end your thread you will need to call looper.quit() on the looper.
Now for the notification you got from Android:
When you create a Handler in a thread, it will be bound to the thread it is created in and when you post runnable using this Handler, the code runs on the thread of the Handler.
So when the system saw that you want to run some code (especially 100ms in future) on a Handler that is bound to a thread that is going to die as soon as it finishes calling the post method it proposed to use Looper.loop() to prevent this thread from terminating and thus enabling you properly run the second Runnable in a still existing thread.
I find the following tutorial very helpful in understanding the concept of looper .
Intro to looper and handler
I am programming in Android environment, and I have in my project a Main Activity, in which there is an AsynkTask class, and separately a Thread object, realized extending Runnable interface. Now, AsynkTask and the Thread can be seen as two worker threads managed by the main thread, that is the Main Activity. How can I do if I want to make possible the communication between the two worker threads, not involving the main thread? How can I use handlers to realize this? I know how to use handlers between main and worker threads. I want to know how use them only between the worker threads, because in this case I can't pass in constructors handlers, because in this case I can not directly instantiate a thread, passing it as a parameter the handler created by the main thread. The main thread must create two worker threads, and they must communicate without the involvement of the main thread.
I hope I have been clear enough.
If you want to use a Handler with a worker thread you have to create a Looper on that Thread as explained in http://developer.android.com/reference/android/os/Looper.html.
Like this:
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
And then you can send messages to mHandler from any other Thread.
My question Is that What is the difference between Thread and Handler
Q1) What are their effects When they are used in 1) Activity 2) Service
Q2) What is difference between them in context with their life span
I am using following codes for them.
1) ---------------------------
final Handler handler = new Handler();
Runnable runnable = new Runnable()
{
public void run()
{
// do somthing
handler.postDelayed(this, 1000);
}
};
runnable.run();
2) ---------------------------
handler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);
}
};
new Thread(new Runnable()
{
public void run()
{
while(true)
{
try
{
Thread.sleep(1000);
handler.sendEmptyMessage(0);
} catch (InterruptedException e) {}
}
}
}).start();
Handler:
handler is used to do looper thing.that is to perform same task number of time.
handler can be executed on main thread.
about Handler if its used in service it may get stop if phone state change to sleep.
u can update the UI through handler if it used in activity.
Thread:
Thread is used to things on separate than the main thread of an activity.
thread always runs in background even if phone state changes to sleep mode.
u cant update the UI of as its not running on main thread.it can be done using asynctask not using simple java thread.
Q0) What is the difference between a thread and a handler?
A Thread is the same as it always is in programming. Each thread executes a single call to a method and then terminates. Each thread runs in parallel with every other thread. Threads are in short the way you have more than one thing happening at once.
Passing information between threads is notoriously difficult...
A Handler is Android's way of passing a message from one thread to another. Specifically it allows you to pass a set of instructions as a Runnable into a thread for that thread to execute. Typically they are used as a way for a thread to report its result back to the main thread when it's complete.
Q1) What are their effects When they are used in 1) Activity 2) Service
There is no difference between the way these two items behave in a service or an activity in general except that a service can exist in its own process if android is instructed to do so. Threads in different processes can not directly talk to one another. Services are there to share data,functionality and in some cases threads between activities. There is no requirement for them to have their own thread.
The one major point to note is that only the main thread can update the UI (activity).
Also networking specifically can not be done on the main thread. Networking is usually done from within a service so that the results can be shared but this is not necessary.
The limitations around what must and must not be done in the main thread make threading a little tricky, but these limitations are there to help you avoid freezing the UI unexpectedly.
Q2) What is difference between them in context with their life span I am using following codes for them.
Difficult to answer as I don't understand the purpose of your code.
As an example. Android no longer allows you to do any networking on the main thread as this could freeze the UI while it's waiting for the server to respond over a poor wifi connection. To change something on the UI based on something retrieved from the network you must use a thread to do the networking and pass the data back to the main thread to update the UI.
A (doctored) snippet from my code looks like this:
private final Handler handler = new Handler();
#Override
protected void onCreate( Bundle savedInstanceState ) {
// irreverent to the example
super.onCreate(savedInstanceState);
super.setContentView(R.layout.abstract_main_view);
// Here's the example
Thread networkThread = new Thread() {
#Override
public void run() {
// This could take several seconds
final Collection<Player> players = service.lookupAllPlayers();
Runnable uiUpdate = new Runnable() {
#Override
public void run() {
// This is quick, just adding some text on the screen
showPlayers(players);
}
};
handler.post(uiUpdate);
}
};
networkThread.start();
}
In this example:
The handler is created and exists for the duration of this activity. Because this class is constructed by the main thread, the Handler is also. This means that all messages posted to this handler will be executed by main.
networkThread is created and started by the main thread in onCreate. This lives until it has retrieved the data from the network and posted a response back to the main thread. Then it's done.
The Runnable uiUpdate is created by networkThread once all data is retrieved. It does not have a thread associated and so does not execute right away. Instead it is posted back to main using the handler. It is then executed on the main thread and discarded once complete.
One can use a Handler to inform one thread of events from another thread.
Typical usage would be to inform the UI Thread from other threads.
We can not modify UI elements from other threads directly. So we can define a Handler as a member of an Activity instead.
Activities are created on the UI Thread so this handler also is on UI Thread.
So then from another thread we send a message to the Handler. And on receiving the message the Handler modifies some UI elements.