I came across this code in a very basic Handler tutorial. The code is working fine but I do not understand why I have to use Handler for progressDialog.dismiss()
??? I removed the Handler part and placed progressDialog.dismiss()
in the run()
method and it worked fine. So why used Handler???
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class HandlerThread extends Activity{
private Button start;
private ProgressDialog progressDialog;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
start = (Button) findViewById(R.id.Button01);
start.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
fetchData();
}
});
}
protected void fetchData() {
// TODO Auto-generated method stub
progressDialog = ProgressDialog.show(this, "", "Doing...");
new Thread() {
public void run() {
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
}
messageHandler.sendEmptyMessage(0);
}
}.start();
}
private Handler messageHandler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
progressDialog.dismiss();
}
};
}
First: Let us know what is thread:
Second: Let us know about the application thread:-
Android UI-Toolkit is not thread safe
Handler class:
android.os.Handler
Instance of handler is made
Handler handlerObject = new Handler();
Final piece on using handler is to use Runnable Interface:
Class NameOfClass implements Runnable
{
Public void run()
{
//Body of run method
}
}
Putting all together
//Create handler in the thread it should be associated with
//in this case the UI thread
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
while(running){
//Do time consuming stuff
//The handler schedules the new runnable on the UI thread
handler.post(new Runnable() {
//Ex.. using progressbar to set the pogress
//Updating the UI is done inside the Handler
});
}
}
};
new Thread(runnable).start();
From the documentation of View
:
You must always be on the UI thread when calling any method on any view. If you are doing work on other threads and want to update the state of a view from that thread, you should use a
Handler
.
In your example, when you've to call the dismiss()
method on the ProgressDialog
, as per the above documentation, you must do so from the UI thread. The messageHandler
is initialized to an instance of a Handler
when the HandlerThread
class is instantiated (presumably on the UI thread).
From the documentation of Handler
:
Each
Handler
instance is associated with a single thread and that thread's message queue. When you create a newHandler
, 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.
So to communicate with the UI thread from your new thread, just post a message to the Handler
created on the UI thread.
If you call methods on a View
from outside the UI thread, it invokes undefined behaviour, which means, it may appear to work fine. But it's not always guaranteed to work fine.
The easier the better. Instead of using a handler, you could try to use the following code:
runOnUiThread(
new Runnable() {
public void run()
{
//Update user interface here
}
}
);
Don't make your life to complicated ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With