简体   繁体   English

正在从附加有后台线程的处理程序中显示Toast。 不确定如何发生?

[英]Toast is being displayed from a handler which is attached with a background thread. Not sure how that can happen?

I used HandlerThread and then used its looper to create a new Handler so that it can run operations on a non-UI thread. 我使用了HandlerThread,然后使用其循环程序创建了一个新的Handler,以便它可以在非UI线程上运行操作。 In the runnable which is posted to the handler, I added Toast messages to be displayed. 在发布到处理程序的runnable中,我添加了Toast消息以进行显示。 I expected that to cause a problem as you can't touch UI components from the non-UI thread, but it still works and that toast is still being shown. 我希望这会引起问题,因为您无法通过非UI线程触摸UI组件,但是它仍然可以正常工作,并且仍在显示Toast。 Can anyone explain why toast is being displayed from the non-UI thread? 谁能解释为什么从非UI线程显示吐司?

 //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);
            }
        });

I checked Toast.java and saw that the looper initializes itself with Looper.myLooper(). 我检查了Toast.java,发现循环程序使用Looper.myLooper()进行了初始化。

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

From the doc : 文档

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

And the currentThread is the HandlerThread, not the main thread. 而currentThread是HandlerThread,而不是主线程。 Hence, I am unable to understand how the toast is being displayed from the non-UI thread, or if it is something plain simple I am missing to see. 因此,我无法理解如何从非UI线程显示吐司,或者我是否看不见它是否很简单。

For showing Toast you used getContext() as a context. 为了显示Toast,您使用了getContext()作为上下文。

getContext() - Returns the context the view is currently running in. Usually the currently active Activity. getContext() -返回视图当前正在其中运行的上下文。通常是当前活动的Activity。

While you are using fragment so it will take activity context where fragment will resides in activity. 当您使用片段时,它将使用活动上下文,其中片段将驻留在活动中。

That's why Toast shown. 这就是为什么烤面包显示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM