MainLooper vs runOnUiThread

时间:2014-06-12 20:38:39

标签: java android multithreading

我是Android的新手。下面和我应该使用哪一个在主线程上运行方法之间的区别是什么?

1)

Handler mainHandler = new Handler(getApplicationContext().getMainLooper());
Runnable myRunnable = new Runnable() {
    @Override
    public void run() {
        // Do some thing
    }
};
mainHandler.post(myRunnable);

2)

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        // Do some thing
    }
});

2 个答案:

答案 0 :(得分:3)

来自Activity的源代码:

public final void runOnUiThread(Runnable action) {
    if (Thread.currentThread() != mUiThread) {
        mHandler.post(action);
    } else {
        action.run();
    }
}

您可以看到runOnUiThread几乎完全相同,即在Runnable上发布Handler。主要区别在于,如果你已经在ui线程上调用它,它会直接运行。

我会使用第二个,因为当你可以使用Activity时,不需要创建另一个处理程序。

第一种情况是,当您手头上没有ActivityView时可以使用Runnable(例如Service 1}} S)。

另外,您会注意到Handler的默认构造函数使用当前线程的Looper,这意味着如果您创建的话,您不必获取mainLooper来自UI线程的Handler

答案 1 :(得分:3)

在您发布的两个代码示例之间,没有真正的区别,您可以使用较短的表示法。然而,有一个相关的结构,其中 有很大的不同:

public class MyActivity extends Activity implements Handler.Callback {

     // constructors and onCreate and stuff

    private static final int FOO = 1;
    private static final int BAR = 2;

    private final Handler mHandler = new Handler(Looper.getMainLooper(), this);

    private void sendFooMessage(int arg1, String arg2) {
        mHandler.sendMessage(mHandler.obtainMessage(FOO, arg1, 0, arg2));
    }

    @Override
    public boolean handleMessage(Message msg) {
        switch(msg.what) {
        case FOO:
             //handle the foo event
             return true;
        case BAR:
             //handle the bar action
             return true;
        }
        return false;
    }
}

这个结构特别之处在于你没有创造任何垃圾(*)。没有单一Runnable实例进入垃圾收集器。 Handler.obtainMessage(...)方法从池中获取Message个对象,一次又一次地重用它们。

如果您在保持60fps很重要的情况下触发消息,这种无垃圾构造可以防止垃圾收集器暂停,从而帮助保持一切顺利。

*)不管消息本身如何,你仍然需要照顾args和东西。