为什么要使用Handler?

时间:2012-09-07 06:34:27

标签: android

我在一个非常基本的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();

        }
    };
}

4 个答案:

答案 0 :(得分:31)

为什么在Android中使用Handler?


首先:让我们知道什么是主题:

  • 线程有助于多任务处理
  • 线程可以被教导为在主进程下运行的迷你进程
  • 线程至少启用外观并行执行

第二:请告诉我们应用程序主题: -

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

Android UI-Toolkit不是线程安全的

  • 如上所述,android主线程中有很多组件,现在假设其中一个组件需要很长时间才能执行 这使主线程无响应,它将显示 应用程序无响应
  • 子线程无法直接操作应用程序(主)线程 在android
  • 处理程序充当接口并从中收集消息 子线程并逐个更新主应用程序线程 消息到达,线程处理程序在主线程中实现。

处理程序类:

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

Figure

  • 从上图中我们可以看到每个线程都由一个处理 Handler类的实例
  • 线程在消息的帮助下相互通信
  • 此处理程序类有助于保持同步协调的类型 线程允许它们一起运行实现多线程

处理程序的实例

Handler handlerObject = new Handler();

使用处理程序的最后一件事是使用Runnable Interface:

  • handler class利用runnable接口实现多线程
  • 我们覆盖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();

答案 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方法中向处理程序和处理程序发送消息,处理此消息。