【问题标题】:Why run Handler in main Looper thread为什么在 Looper 主线程中运行 Handler
【发布时间】:2018-12-13 09:29:19
【问题描述】:

我读到 Android Handler 可用于与Looper 主线程通信以发布将与视图交互的消息(因为只有主线程可以与那里的视图交互)

但我经常看到类似下面示例的代码在主线程中运行Handler。为什么这是一个好主意,除非有像postDelayed(new Runnable()...这样的延迟

对此的任何解释都会很好

public class TaleDemoActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo);

        new Handler().post(new Runnable() {
            @Override
            public void run() {
                new Handler().post(new Runnable() {
                    @Override
                    public void run() {
                        new Tale("Hello runnables!").tell();
                    }
                });
                new Handler().post(new Runnable() {
                    @Override
                    public void run() {
                        new Tale("Hello runnables!").at().tell();
                    }
                });
            }
        });

        new Handler().post(new TestRunnable());
        new Handler().post(new TestStaticRunnable());

        new Handler().post(new TestAbstractRunnable() {
            @Override
            public void run() {
                new Tale("Hello abstract runnable!").tell();
            }
        });
        new Handler().post(new TestInterfaceRunnable() {
            @Override
            public void run() {
                new Tale("Hello test interface runnable!").tell();
            }
        });

        new Tale().at().tell();
    }

    class TestRunnable implements Runnable {
        @Override
        public void run() {
            new Tale("Hello testRunnable!").tell();
        }
    }

    static class TestStaticRunnable implements Runnable {
        @Override
        public void run() {
            new Tale("Hello testStaticRunnable!").tell();
        }
    }

    abstract class TestAbstractRunnable implements Runnable {

    }

    interface TestInterfaceRunnable extends Runnable {

    }
}

【问题讨论】:

  • 你从哪里得到这个代码?它包含在处理程序中!没有人应该那样编程。
  • 刚刚在 GitHub 上阅读代码并在那里找到了它

标签: android android-handler


【解决方案1】:

Handler 不仅仅用于与 main Looper 通信。

Looper 是一个循环消息队列并分派它们的类,每个实例使用一个Thread

HandlerThread 是一个 Thread,它还附加了一个 Looper

您的应用程序的“主要”Thread 也是 HandlerThread

当您使用空构造函数实例化 Handler 时,Handler 将附加到您正在创建实例的 ThreadLooper 上。例如,如果您在ActivityonCreate 中创建Thread,则Handler 将附加到主(UI)Thread,因为生命周期回调在那里执行。

当您调用post(Runnable) 时,Runnable 将在HandlerLooper 附加到的线程上运行。因此,如果您在Activity 的生命周期回调之一中创建Handler,那么无论您从哪个Thread 发布Runnable,它将始终在主Thread 上执行

这是最常见的用法,也是您的代码所做的,但它不是唯一的。例如,您可以实例化一个HandlerThread,然后从Activity 生命周期回调中,您可以发布一个执行很长时间操作的Runnable,它不会阻塞您的UI,因为它将在不同的Thread 上执行。

post(Runnable) 的另一种用法(有时是对奇怪的 UI 错误的通用脏修复)是从主线程调用它,只是为了延迟执行,直到整个方法执行完毕。

fun onCreate(savedInstanceState: Bundle?) {
    Handler().post {
        // code here is executed after `onCreate` has returned
    }
    // code here is executed before the one posted on the Handler
}

【讨论】:

  • 谢谢,如果我在onCreate 中执行runOnUiThread(new Runnable()..,它会立即运行,为什么Handler 就像你说的那样,在onCreate 之后运行? runOnUiThread 在内部使用 Handler 对吗??
  • runOnUiThread 将使用Handler 仅当您不是从主线程调用它时,如果您从主线程调用它,它将执行Runnable 而不会将其发布到@987654361 @。顺便说一句,在 Android Studio 中,您可以左键单击按住 ctrl 的方法,它将跳转到源代码;)
  • 哦,很高兴知道,谢谢,我想我最了解你了 :)
  • 没问题,有更多疑问欢迎追问
猜你喜欢
  • 1970-01-01
  • 2012-10-04
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-17
相关资源
最近更新 更多