从处理程序显示Toast,该处理程序附加了后台线程。不知道怎么会发生这种情况?

问题描述 投票:2回答:1

我使用了HandlerThread,然后使用它的looper创建一个新的Handler,以便它可以在非UI线程上运行操作。在发布到处理程序的runnable中,我添加了要显示的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用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,而不是主线程。因此,我无法理解如何从非UI线程显示toast,或者如果它是一个简单的东西,我很想看到。

java android android-handler android-thread
1个回答
-1
投票

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

getContext() - 返回视图当前运行的上下文。通常是当前活动的Activity。

当您使用片段时,它将采用片段将驻留在活动中的活动上下文。

这就是Toast显示的原因。

© www.soinside.com 2019 - 2024. All rights reserved.