为什么在runOnUiThread使用Handler时也一样?

时间:2012-09-27 09:19:10

标签: android multithreading android-asynctask handler

我遇到过HandlersrunOnUiThread个概念。但对我来说,它们似乎仍然存在疑问,因为它们确实存在哪些不同之处。

它们都旨在从后台线程执行UI操作。但是,当我们在两种方法中进行选择时,要考虑的因素是什么。

例如,考虑在后台执行网络服务的Runnable Thread,现在我想更新用户界面。

更新我的UI的最佳方法是什么?我应该选择Handler还是runOnUiThread

我仍然知道我可以使用AsyncTask并使用onPostExecute。但我只想知道其中的区别。

5 个答案:

答案 0 :(得分:71)

Activity.runOnUiThread()是更通用的Handlers的特例。使用Handler,您可以在自己的线程中创建自己的事件查询。使用Handlers Thread不会意味着“代码将在UI线程上运行”。默认情况下,处理程序绑定到Handler,从中实例化它们。

要创建保证绑定到UI(主)线程的Handler,您应该创建绑定到 Main Looper Handler mHandler = new Handler(Looper.getMainLooper()); 对象,如下所示:

runOnuiThread()

此外,如果您检查Handler方法的实现,它正在使用 public final void runOnUiThread(Runnable action) { if (Thread.currentThread() != mUiThread) { mHandler.post(action); } else { action.run(); } } 来执行以下操作:

Runnable action

正如您在上面的代码段中看到的,如果从UI线程调用runOnUiThread(),则会立即执行Handler。否则,它会将其发布到{{1}},这将在稍后的某个时间点执行。

答案 1 :(得分:1)

如果你为任何正在运行的任务启动一个线程,那么处理程序有很多工作,如消息传递和频繁的UI更新.A Handler允许你发送和处理与线程的MessageQueue相关的Message和Runnable对象, ,这在许多应用程序中非常有用,如蓝牙聊天,wifi聊天...和处理程序有方法PostDelay和PostAtTime,您可以通过它来播放任何视图动画和更改可见性等等

你必须看看这个

http://developer.android.com/guide/components/processes-and-threads.html

http://developer.android.com/tools/testing/activity_testing.html

答案 2 :(得分:1)

按照HitOdessit的回答。

你可以创建一个这样的类。

public class Global{
    private static Handler mHandler = new Handler(Looper.getMainLooper());
    public static void runOnUiThread(Runnable action){
        mHandler.post(action);
    }
}

然后这样称呼它。

Global.runOnUiThread(new Runnable(){
    //Your code
});

这可以在任何地方运行(您可以访问Global类)。

答案 3 :(得分:0)

处理程序是做旧事物的旧方式(API级别1),然后引入了AsycTask(API级别3),并更加注重使用runOnUIThread(API级别1)。您应该尽可能避免使用处理程序,并根据您的需要选择其他两种处理程序。

答案 4 :(得分:0)

  

更新我的UI的最佳方法是什么?我应该选择Handler还是runOnUiThread?

如果您的Runnable需要更新用户界面,请将其发布到runOnUiThread

但是并不总是可以在UI线程上发布Runnable

考虑场景,您需要执行网络/ IO操作或调用Web服务。在这种情况下,您无法将Runnable发布到UI线程。它将抛出android.os.NetworkOnMainThreadException

这些类型的Runnable应该在HandlerThread之类的不同线程上运行。完成操作后,您可以使用已与UI线程关联的Handler将结果发布回UI线程。

public void onClick(View view) {

    // onClick on some UI control, perform Network or IO operation

    /* Create HandlerThread to run Network or IO operations */
    HandlerThread handlerThread = new HandlerThread("NetworkOperation");
    handlerThread.start();

    /* Create a Handler for HandlerThread to post Runnable object */
    Handler requestHandler = new Handler(handlerThread.getLooper());

   /* Create one Handler on UI Thread to process message posted by different thread */

    final Handler responseHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            //txtView.setText((String) msg.obj);
            Toast.makeText(MainActivity.this,
                    "Runnable on HandlerThread is completed and got result:"+(String)msg.obj,
                    Toast.LENGTH_LONG)
                    .show();
        }
    };

    NetworkRunnable r1 = new NetworkRunnable("http://www.google.com/",responseHandler);
    NetworkRunnable r2 = new NetworkRunnable("http://in.rediff.com/",responseHandler);
    requestHandler.post(r1);
    requestHandler.post(r2);

}

class NetworkRunnable implements Runnable{
    String url;
    Handler uiHandler;

    public NetworkRunnable(String url,Handler uiHandler){
        this.url = url;
        this.uiHandler=uiHandler;
    }
    public void run(){
        try {
            Log.d("Runnable", "Before IO call");
            URL page = new URL(url);
            StringBuffer text = new StringBuffer();
            HttpURLConnection conn = (HttpURLConnection) page.openConnection();
            conn.connect();
            InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
            BufferedReader buff = new BufferedReader(in);
            String line;
            while ((line = buff.readLine()) != null) {
                text.append(line + "\n");
            }
            Log.d("Runnable", "After IO call:"+ text.toString());

            Message msg = new Message();

            msg.obj = text.toString();

            /* Send result back to UI Thread Handler */
            uiHandler.sendMessage(msg);


        } catch (Exception err) {
            err.printStackTrace();
        }
    }
}