为什么使用处理程序?

我在一个非常基本的Handler教程中遇到了这个代码。 代码工作正常,但我不明白为什么我必须使用处理程序progressDialog.dismiss() ??? 我删除了处理程序部分,并在run()方法中放置progressDialog.dismiss() ,它工作正常。 那么为什么使用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(); } }; } 

Solutions Collecting From Web of "为什么使用处理程序?"

View的文档 :

在任何视图中调用任何方法时,您都必须在UI线程上。 如果您正在其他线程上工作,并想从该线程更新视图的状态,则应使用Handler

在你的例子中,当你必须调用ProgressDialog上的dismiss()方法时,根据上面的文档,你必须从UI线程中这样做。 当HandlerThread类被实例化时(假设在UI线程上), messageHandler被初始化为Handler一个实例。

Handler的文档 :

每个Handler实例都与单个线程和该线程的消息队列相关联。 当你创build一个新的Handler ,它绑定到正在创build它的线程的线程/消息队列 – 从这一点开始,它将把消息和可运行的消息传递给消息队列,并在消息出来时执行它们队列。

所以要从新线程与UI线程进行通信,只需将消息发布到UI线程上创build的Handler

如果您从UI线程外部调用View上的方法,则会调用未定义的行为 ,这意味着它可能正常工作。 但是并不总能保证正常工作。

为什么要在Android中使用Handler?


第一:让我们知道什么是线程:

  • 线程有助于多任务
  • 线程可以作为在主进程下运行的小型进程来教授
  • 线程至less使外观平行执行

第二:让我们知道应用程序线程: –

  • 当android应用程序第一次启动时,运行时系统将创build一个主线程,这个主线程将负责执行android中的所有组件

Android UI-Toolkit不是线程安全的

  • 如上所述,在android主线程中有很多组件,现在假设其中一个组件需要很长时间才能执行,这会导致主线程无响应 ,并显示应用程序无响应
  • 子线程不能直接操作android中的应用程序(主)线程
  • Handler作为接口,收集来自子线程的消息,并在消息到达时逐一更新主应用程序线程,Thread处理程序在主线程中实现。

处理程序类:

  • 为了multithreading的目的,我们将使用来自包android.os.Handler处理器类
  • 每个线程都由一个处理程序类的一个实例处理

数字

  • 从上图我们可以看到,每个线程都由Handler类的一个实例处理
  • 线程在消息的帮助下彼此通信
  • 这个处理程序类通过允许它们一起运行实现multithreading来帮助保持同步协调黑白线程

处理程序的实例被创build

 Handler handlerObject = new Handler(); 

使用处理程序的最后一部分是使用Runnable接口:

  • 处理程序类利用可运行的接口来实现multithreading
  • 我们重写run方法来执行一个指定次数的线程

 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(); 

越容易越好。 而不是使用处理程序,您可以尝试使用以下代码:

 runOnUiThread( new Runnable() { public void run() { //Update user interface here } } ); 

不要让你的生活变得复杂;)

当一个应用程序启动时,android系统启动一个具有主线程的进程,主线程负责处理UI渲染和事件。 Android UI不是线程安全的,所以我们只能通过Event线程访问android UI。 在你的程序中,你已经通过以下代码块定义了另一个线程,

  new Thread() { public void run() { try { Thread.sleep(8000); } catch (InterruptedException e) { } messageHandler.sendEmptyMessage(0); } }.start(); 

现在,如果您想closures进度对话框,则只能在事件线程中进行。 处理程序用于处理/处理消息队列的消息。 处理程序与一个线程相关联,在你的情况下,它在事件线程中,默认情况下它将关联线程,在线程中创build它。 通过messageHandler.sendEmptyMessage()另一个线程发送消息给处理程序,并在handleMessage方法中处理这个消息。