Toast отображается из обработчика, который прикреплен к фоновому потоку.Не уверен, как это может произойти? - PullRequest
0 голосов
/ 04 марта 2019

Я использовал HandlerThread, а затем использовал его петлитель для создания нового обработчика, чтобы он мог запускать операции в потоке без пользовательского интерфейса.В runnable, который публикуется в обработчике, я добавил сообщения Toast для отображения.Я ожидал, что это вызовет проблему, поскольку вы не можете касаться компонентов пользовательского интерфейса из потока, не являющегося пользовательским интерфейсом, но он все еще работает, и этот тост все еще отображается.Кто-нибудь может объяснить, почему 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, а не основной поток.Следовательно, я не могу понять, как отображается тост из потока, не являющегося пользовательским интерфейсом, или если это что-то простое, чего мне не хватает.

1 Ответ

0 голосов
/ 04 марта 2019

Для показа Toast вы использовали getContext() в качестве контекста.

getContext() - Возвращает контекст, в котором в данный момент запущено представление. Обычно текущая активная активность.

Пока выиспользование фрагмента, поэтому он получит контекст активности, где фрагмент будет находиться в активности.

Вот почему показан тост.

...