Android 子线程创建处理程序的角色是什么

Android 子线程创建处理程序的角色是什么,android,handler,android-looper,Android,Handler,Android Looper,1.我在子线程中创建处理程序时遇到问题 像 } 上述代码将崩溃 Process: com.example.hellokai.kotlindemo, PID: 27485 android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can t

1.我在子线程中创建处理程序时遇到问题

} 上述代码将崩溃

Process: com.example.hellokai.kotlindemo, PID: 27485
                                               android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
                                                   at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6986)
                                                   at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1074)
                                                   at android.view.View.requestLayout(View.java:19889)
                                                   at android.view.View.requestLayout(View.java:19889)
                                                   at android.view.View.requestLayout(View.java:19889)
                                                   at android.view.View.requestLayout(View.java:19889)
                                                   at android.support.constraint.ConstraintLayout.requestLayout(ConstraintLayout.java:1959)
                                                   at android.view.View.requestLayout(View.java:19889)
                                                   at android.widget.TextView.checkForRelayout(TextView.java:7369)
                                                   at android.widget.TextView.setText(TextView.java:4480)
                                                   at android.widget.TextView.setText(TextView.java:4337)
                                                   at android.widget.TextView.setText(TextView.java:4312)
                                                   at com.example.hellokai.kotlindemo.Main4Activity$1$1.handleMessage(Main4Activity.java:40)
                                                   at android.os.Handler.dispatchMessage(Handler.java:102)
                                                   at android.os.Looper.loop(Looper.java:154)
                                                   at com.example.hellokai.kotlindemo.Main4Activity$1.run(Main4Activity.java:45)
2.我知道在主线程中更新ui,在主线程中创建处理程序来创建,然后在子线程中发送消息给处理程序可以更新ui

3.我的问题是在子线程中创建的处理程序的角色是什么?我们什么时候需要这样做?这个场景有什么用

希望有人能解决我的困惑

我在子线程中创建处理程序时遇到问题。 您正在从后台线程更新ui

例如,您可以从线程发送消息并更新ui,如

private Handler handler = new Handler(Looper.getMainLooper()) {
    @Override
    public void handleMessage(Message msg) {
        Toast.makeText(Main4Activity.this.getApplicationContext(), "handler msg", Toast.LENGTH_SHORT).show();

        mTextView.setText((String)msg.obj);
    }
};
然后

  new Thread() {
        @Override
        public void run() {

            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Message msg = Message.obtain(); // Creates an new Message instance
            msg.obj = "Hello";
            handler.sendMessage(msg);

        }
    }.start();
或者,如果您只是想要一个延迟,那么就不需要像pskink在评论中提到的那样使用线程、循环器和睡眠

我知道在主线程中更新ui,在主线程中创建处理程序来创建,然后在子线程中向 处理程序可以更新用户界面。 是的,您是对的。您可以在ui线程上创建处理程序。您可以从该线程发送消息并更新ui

我的问题是在子线程中创建的处理程序的角色是什么? 处理程序与线程的循环器相关联。如果您在ui中有一个处理程序,它的线程将与其关联。在您的例子中,它位于线程内,因此处理程序与该线程循环器相关联

我们什么时候需要这样做?这个场景有什么用

当您希望从后台线程到ui线程或从ui线程到后台线程进行通信时。

您的代码

new Thread() {
    @Override
    public void run() {
        Looper.prepare();
        @SuppressLint("HandlerLeak") Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                Toast.makeText(Main4Activity.this, "handler msg", Toast.LENGTH_SHORT).show();
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                mTextView.setText("100");
            }
        };
        handler.sendEmptyMessage(1);
        Looper.loop();
    }
}.start();
可以重写以使用Android API:

new Handler(getMainLooper()).postDelayed(
new Runnable() {
    @Override
    public void run() {
                Toast.makeText(Main4Activity.this, "handler msg", Toast.LENGTH_SHORT).show();
                mTextView.setText("100");
        }
    }
}, 200);

还请注意,您的主要问题是在工作线程中已经存在的可运行线程内创建处理程序,您也可以在onCreate的早期创建它。

为什么需要循环器?只需调用Handler.sendEmptyMessageDelayed-不需要任何线程,Loopers和sleep我想知道创建处理程序的子线程为了解决任何问题,在什么情况下需要创建子线程处理程序?在子线程中创建处理程序需要一个looper我读了一些文章,他们说在子线程中可以创建处理程序,处理程序的主线程主要是更新接口,然后子线程创建处理程序的目的是什么?是的,您可以,但创建时使用activity.getMainLooper作为参数。您将不需要prepare/loop谢谢您的回答,我知道如何使用处理程序。在您的示例中,我注意到您创建了一个没有args的处理程序,它将其附加到当前线程谢谢您的回答!从子线程创建处理程序是为了处理耗时的线程,此时handlr应该在工作线程中,而不是在主线程中实现。我看到Google包装了一个HandlerThread类。我不理解HandlerThread和普通线程的区别。为什么不使用Thread类来处理,而是使用HandlerThread类来处理,以及打包HandlerThread类来处理,它的优点是什么?HandlerThread有一个活套。looper有一个消息队列,使线程在消息队列上循环更长时间。java中的线程在its run方法完成后完成。可以使用处理程序在线程之间进行通信。如果您有一个java线程,并且希望它能够存活更长的时间,那么您可以使用looper.loop和looper.prepare。完成后也可以调用quit进行读取。你也可以在家里看这些课程的工作除了看源代码之外你还可以看扩展文档中的服务主题,这也有助于你理解HandlerThread和HandlerThread我回答了你的问题了吗,或者你有困惑吗?很抱歉,我还有其他事情要处理,所以在回答你之前,我理解HandlerThread和Thread的区别。你很好地分享了这篇文章。
new Handler(getMainLooper()).postDelayed(
new Runnable() {
    @Override
    public void run() {
                Toast.makeText(Main4Activity.this, "handler msg", Toast.LENGTH_SHORT).show();
                mTextView.setText("100");
        }
    }
}, 200);