java - Toast 正在从附加了后台线程的处理程序中显示。不确定那是怎么发生的?

标签 java android android-handler android-thread

我使用了 HandlerThread,然后使用它的循环器创建了一个新的 Handler,以便它可以在非 UI 线程上运行操作。在发布到处理程序的可运行对象中,我添加了要显示的 Toast 消息。我预计这会导致问题,因为您无法从非 UI 线程触摸 UI 组件,但它仍然有效并且 toast 仍在显示。谁能解释为什么从非 UI 线程显示 toast?

 //Inside a Fragment class
    private Handler handler;
    private HandlerThread mHandlerThread = null;

    public void startHandlerThread() {
        mHandlerThread = new HandlerThread("HandlerThread");
        mHandlerThread.start();
        handler = new Handler(mHandlerThread.getLooper());
    }


    private Runnable submitRunnable = new Runnable() {
        @Override
        public void run() {
            //do some long running operations here
            //Thread.sleep(2000);

            //Check whether currentLooper is the Main thread looper
            boolean isUiThread = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
                    ? Looper.getMainLooper().isCurrentThread()
                    : Thread.currentThread() == Looper.getMainLooper().getThread();

            if (isUiThread) {
                // You are on the UI thread
                Log.d("Thread", "Main thread");
            } else {
                // You are on the non-UI thread
                Log.d("Thread", "Not Main thread"); //This will be printed
            }

            Toast.makeText(getContext(), "toast is shown", Toast.LENGTH_SHORT).show();
        }
    };

    submitButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                handler.post(submitRunnable);
            }
        });

我检查了 Toast.java,发现循环器使用 Looper.myLooper() 初始化了自己。

 if (looper == null) {
            // Use Looper.myLooper() if looper is not specified.
            looper = Looper.myLooper();
        }

来自doc :

myLooper(): Return the Looper object associated with the current thread.

而currentThread是HandlerThread,不是主线程。 因此,我无法理解 toast 是如何从非 UI 线程显示的,或者它是否是我看不到的简单内容。

最佳答案

为了显示 Toast,您使用了 getContext() 作为上下文。

getContext() - 返回 View 当前运行的上下文。通常是当前 Activity 的 Activity。

当您使用 fragment 时,它将采用 fragment 将驻留在 Activity 中的 Activity 上下文。

这就是 Toast 显示的原因。

关于java - Toast 正在从附加了后台线程的处理程序中显示。不确定那是怎么发生的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54976016/

相关文章:

ArrayList 和 RecyclerView 的 java.lang.OutOfMemoryError

android - 通过一些 scrollX 启动 Horizo​​ntalScrollView

android - 从 android 中的信使/处理程序获取待处理消息的列表

android - 在 Android 中被打包为 Intent 后从 Messenger 检索处理程序

android - 如何每 10 秒调用一次函数?

java - 禁用 dropwizard 对特定资源的内部日志记录

Java:在运行时将类作为参数传递

android - 升级到1.4后,Android Studio Gradle错误-错误:原因:https://downloads.gradle.org/distributions/gradle-2.2.1_all.zip

java - Windows 10 CLI UTF-8 编码

Java Swingworker : Not as encapsulated class