Android: Тост в потоке

Как я могу отображать Toast сообщения из потока?

Ответы

Ответ 1

Вы можете сделать это, вызвав метод Activity runOnUiThread из вашего потока:

activity.runOnUiThread(new Runnable() {
    public void run() {
        Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
    }
});

Ответ 2

Мне нравится иметь метод в моей деятельности под названием showToast, который я могу вызвать из любого места...

public void showToast(final String toast)
{
    runOnUiThread(new Runnable() {
        public void run()
        {
            Toast.makeText(MyActivity.this, toast, Toast.LENGTH_SHORT).show();
        }
    });
}

Затем я чаще всего вызываю его из MyActivity в любом потоке, подобном этому...

showToast(getString(R.string.MyMessage));

Ответ 3

Это похоже на другие ответы, однако обновленные для новой доступной apis и намного более чистые. Кроме того, не предполагается, что вы находитесь в Контексте активности.

public class MyService extends AnyContextSubclass {

    public void postToastMessage(final String message) {
        Handler handler = new Handler(Looper.getMainLooper());

        handler.post(new Runnable() {

            @Override
            public void run() {
                Toast.makeText(getContext(), message, Toast.LENGTH_LONG).show();
            }
        });
    }
}

Ответ 4

Как this или this, с Runnable, который показывает Toast. А именно,

Activity activity = // reference to an Activity
// or
View view = // reference to a View

activity.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        showToast(activity);
    }
});
// or
view.post(new Runnable() {
    @Override
    public void run() {
        showToast(view.getContext());
    }
});

private void showToast(Context ctx) {
    Toast.makeText(ctx, "Hi!", Toast.LENGTH_SHORT).show();
}

Ответ 5

Один подход, который работает практически из любого места, в том числе из мест, где у вас нет Activity или View, заключается в том, чтобы захватить Handler в основной поток и показать тост:

public void toast(final Context context, final String text) {
  Handler handler = new Handler(Looper.getMainLooper());
  handler.post(new Runnable() {
    public void run() {
      Toast.makeText(context, text, Toast.DURATION_LONG).show();
    }
  })
}

Преимущество такого подхода состоит в том, что он работает с любым Context, включая Service и Application.

Ответ 6

  • Получите экземпляр обработчика потоков UI и используйте handler.sendMessage();
  • Вызов post() метод handler.post();
  • runOnUiThread()
  • view.post()

Ответ 7

Иногда вам нужно отправить сообщение из другого потока Thread в пользовательский интерфейс. Этот тип сценария возникает, когда вы не можете выполнять операции Network/IO в потоке пользовательского интерфейса.

Ниже приведен пример этого сценария.

  • У вас есть пользовательский интерфейс
  • Вам нужно запустить операцию ввода-вывода, и поэтому вы не можете запустить Runnable в потоке пользовательского интерфейса. Поэтому отправьте свой Runnable обработчику на HandlerThread
  • Получить результат от Runnable и отправить его обратно в поток пользовательского интерфейса и показать сообщение Toast.

Решение:

  • Создайте HandlerThread и запустите его
  • Создайте Handler с Looper from HandlerThread: requestHandler
  • Создайте обработчик с Looper из основного потока: responseHandler и переопределите handleMessage метод
  • post a Runnable задача на requestHandler
  • Внутри задачи Runnable вызовите sendMessage на responseHandler
  • Этот sendMessage вызывает вызов handleMessage в responseHandler.
  • Получить атрибуты из Message и обработать его, обновить интерфейс

Пример кода:

    /* Handler thread */

    HandlerThread handlerThread = new HandlerThread("HandlerThread");
    handlerThread.start();
    Handler requestHandler = new Handler(handlerThread.getLooper());

    final Handler responseHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            //txtView.setText((String) msg.obj);
            Toast.makeText(MainActivity.this,
                    "Runnable on HandlerThread is completed and got result:"+(String)msg.obj,
                    Toast.LENGTH_LONG)
                    .show();
        }
    };

    for ( int i=0; i<5; i++) {
        Runnable myRunnable = new Runnable() {
            @Override
            public void run() {
                try {

                    /* Add your business logic here and construct the 
                       Messgae which should be handled in UI thread. For 
                       example sake, just sending a simple Text here*/

                    String text = "" + (++rId);
                    Message msg = new Message();

                    msg.obj = text.toString();
                    responseHandler.sendMessage(msg);
                    System.out.println(text.toString());

                } catch (Exception err) {
                    err.printStackTrace();
                }
            }
        };
        requestHandler.post(myRunnable);
    }

Полезные статьи:

handlerthreads-and-why-you-should-be-using-them-in-your-android-apps

android-looper-handler-handlerthread-i

Ответ 8

Вы можете использовать Looper для отправки сообщения Toast. Прочтите эту ссылку для более подробной информации.

public void showToastInThread(final Context context,final String str){
    Looper.prepare();
    MessageQueue queue = Looper.myQueue();
    queue.addIdleHandler(new IdleHandler() {
         int mReqCount = 0;

         @Override
         public boolean queueIdle() {
             if (++mReqCount == 2) {
                  Looper.myLooper().quit();
                  return false;
             } else
                  return true;
         }
    });
    Toast.makeText(context, str,Toast.LENGTH_LONG).show();      
    Looper.loop();
}

и он вызывается в вашем потоке. Контекст может быть Activity.getContext() получить из Activity вам нужно показать тост.

Ответ 9

Я сделал этот подход на основе ответа mjaggard:

public static void toastAnywhere(final String text) {
    Handler handler = new Handler(Looper.getMainLooper());
    handler.post(new Runnable() {
        public void run() {
            Toast.makeText(SuperApplication.getInstance().getApplicationContext(), text, 
                    Toast.LENGTH_LONG).show();
        }
    });
}

Хорошо работал у меня.