Android runOnUiThread不是异步

时间:2015-10-09 13:30:45

标签: android multithreading

我有这段代码:

public void updateOptionLists() {
    Log.d("UI", "Called update");
    if (updating){
        return;
    }
    updating = true;
    runOnUiThread(
            new Runnable() {
                @Override
                public void run() {
                    updating = false;
                    updateOptionList();
                    scrollToLastTapped();
                    Log.d("UI","Updating");
                }
            });
    Log.d("UI", "Posted update");
}

我对logcat的期望是这样的:

  • 被叫更新
  • 发布更新
  • 更新

据我所知runOnUi应该是异步的,对吧?并且考虑到调用的函数改变了视图,这需要一段时间,这应该是异步运行的。正确?

所以我看看我的logcat:

  • 被叫更新
  • 更新
  • 发布更新

为什么会这样?我如何确保它以异步方式运行?

7 个答案:

答案 0 :(得分:8)

runOnUiThread将在主线程上执行你的代码,在这个例子中,它也似乎是从它调用的地方。这解释了你看到的日志语句的顺序 - 所有代码都在一个线程上执行,因此同步per the documentation(我的重点):

  

在UI线程上运行指定的操作。 如果当前线程是UI线程,则立即执行操作。如果当前线程不是UI线程,则该操作将发布到UI线程的事件队列中。

runOnUiThread通常用于执行主线程上的代码来自不同的(即后台线程)。使用这个单独的后台线程将使任务异步。如果要使用后台线程计算的结果修改UI,则需要在该任务结束时回调UI线程。

Android提供了几种机制,用于在后台线程上进行工作,然后回发到主线程(对于后一种操作,并非明确地使用runOnUiThread)。要阅读的好东西包括ThreadHandlerAsyncTaskService等。

答案 1 :(得分:2)

  

据我所知,runOnUi应该是异步的,对吧?

正如名称所示,

runOnUiThread在UI线程上运行,UI线程是应用程序的主线程。它与该线程中运行的其他代码同步运行,并与其他线程中的代码异步运行。 单词'异步'没有上下文没有意义:某些代码可以与代码的其他部分异步运行,这意味着代码的这些部分在不同的线程中运行。说某些事情应该是异步的'没有这种背景就毫无意义。

答案 2 :(得分:0)

是在UI线程上运行的updateOptionLists吗?

如果是这种情况,我希望这种行为可以。

在正常情况下,您使用后台线程中的runOnUiThread再次进入Ui线程..

答案 3 :(得分:0)

因为你在ui prosess上调用upadetOptionLists(),所以upadetOptionLists()和runUiThread()都在同一个线程中运行。

要选择theam,您需要在其他新主题中运行内容,如下所示

   public void updateOptionLists() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                Log.d("UI", "Called update");
                if (updating){
                    return;
                }
                updating = true;
                runOnUiThread(
                        new Runnable() {
                            @Override
                            public void run() {
                                updating = false;
                                updateOptionList();
                                scrollToLastTapped();
                                Log.d("UI","Updating");
                            }
                        });
                Log.d("UI", "Posted update");
            }
        }).start();
    }

答案 4 :(得分:0)

要访问视图,您必须位于UI线程(主线程)中。因此,runOnUiThread将在其上执行。

你必须在另一个线程中完成长时间的工作,只需要调用runOnUiThread来做一些改变颜色或文本但不计算它的事情。

答案 5 :(得分:0)

来自文档:

在UI线程上运行指定的操作。如果当前线程是UI线程,则立即执行该操作。如果当前线程不是UI线程,则该操作将发布到UI线程的事件队列中。

http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)

答案 6 :(得分:0)

多线程编程:理论与实际 小狗照片解释是最好的pic.twitter.com/adFy17MTTI

- CianÓMaidín(@Cianomaidin)6. april 2015

但开玩笑说。

如果要测试线程的相关性,请尝试:

runOnUiThread(
        new Runnable() {
            @Override
            public void run() {
                updating = false;
                updateOptionList();
                scrollToLastTapped();
                Thread.sleep(100);
                Log.d("UI","Updating");
            }
        });