我在一个非常基本的Handler教程中遇到了这段代码。代码工作正常,但我不明白为什么我必须使用Handler for progressDialog.dismiss()
???我删除了处理程序部分并将progressDialog.dismiss()
放在run()
方法中,它运行正常。那么为什么要使用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();
}
};
}
答案 0 :(得分:31)
首先:让我们知道什么是主题:
第二:请告诉我们应用程序主题: -
Android UI-Toolkit不是线程安全的
处理程序类:
android.os.Handler
处理程序的实例
Handler handlerObject = new Handler();
使用处理程序的最后一件事是使用Runnable Interface:
Class NameOfClass implements Runnable
{
Public void run()
{
//Body of run method
}
}
全力以赴
//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();
答案 1 :(得分:17)
From the documentation of View
:
在调用任何方法时,您必须始终在UI线程上 查看。如果您正在其他线程上工作并想要更新 该线程的视图状态,您应该使用
Handler
。
在您的示例中,当您根据上述文档调用dismiss()
上的ProgressDialog
方法时,必须从UI线程执行此操作。实例化messageHandler
类时,Handler
被初始化为HandlerThread
的实例(可能是在UI线程上)。
From the documentation of Handler
:
每个
Handler
实例都与一个线程相关联 线程的消息队列。当您创建新的Handler
时,它将被绑定 正在创建它的线程的线程/消息队列 - 来自 那一点,它将为该消息传递消息和可运行的消息 队列并在它们从消息队列中出来时执行它们。
因此,要与新线程中的UI线程进行通信,只需将消息发布到UI线程上创建的Handler
。
如果从UI线程外部调用View
上的方法,它会调用未定义的行为,这意味着可能会出现以正常工作。但总是保证能够正常工作。
答案 2 :(得分:5)
越容易越好。 您可以尝试使用以下代码,而不是使用处理程序:
runOnUiThread(
new Runnable() {
public void run()
{
//Update user interface here
}
}
);
不要让你的生活变得复杂;)
答案 3 :(得分:2)
当应用程序启动时,android系统启动一个具有主线程的进程,该主线程负责处理UI呈现和事件。 Android UI不是线程安全的,所以我们只能通过Event线程访问android UI。在您的程序中,您通过以下代码块定义了除事件之外的另一个线程:
new Thread() {
public void run() {
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
}
messageHandler.sendEmptyMessage(0);
}
}.start();
现在,如果要关闭进度对话框,则只能在事件线程中执行此操作。 处理程序用于处理/处理消息队列的消息。 Handler与一个线程相关联,在你的情况下它与事件线程相关联,因为默认情况下它会关联正在创建它的线程。通过messageHandler.sendEmptyMessage()另一个线程在handleMessage方法中向处理程序和处理程序发送消息,处理此消息。