10 ответов:
вы можете сделать это путем вызова
Activity' srunOnUiThreadметод из вашего потока:activity.runOnUiThread(new Runnable() { public void run() { Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show(); } });
мне нравится иметь метод в моей деятельности под названием
showToastкоторый я могу позвонить из любого места...public void showToast(final String toast) { runOnUiThread(() -> Toast.makeText(MyActivity.this, toast, Toast.LENGTH_SHORT).show()); }Я тогда чаще всего называю его изнутри
MyActivityна какой-нить подобное...showToast(getString(R.string.MyMessage));
Это похоже на другие ответы, однако обновляться на новые API и намного чище. Кроме того, не предполагает, что вы находитесь в контексте деятельности.
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(); } }); } }
как этой или этой С
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(); }
один подход, который работает практически везде, в том числе из мест, где у вас нет
ActivityилиView, чтобы захватить aHandlerв основной поток и показать тост: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.
иногда, вы должны отправить сообщение из другой
Threadв поток пользовательского интерфейса. Этот тип сценария возникает, когда вы не можете выполнить операции сети/ввода-вывода в потоке пользовательского интерфейса.ниже пример обрабатывает этот сценарий.
- у вас есть UI Thread
- вы должны начать операцию ввода-вывода и, следовательно, вы не можете запустить
Runnableв потоке пользовательского интерфейса. Так что разместите свойRunnableобработчикуHandlerThread- получить результат от
Runnableи отправить его обратно в поток пользовательского интерфейса и показатьToastсообщение.устранение:
- создать HandlerThread и запустить его
- создать проводник С Looper С
HandlerThread:requestHandler- создать обработчик с Петлителем из основного потока:
responseHandlerи переопределитьhandleMessageметодpostaRunnableзадачиrequestHandler- внутри
Runnableзадач, называютsendMessageнаresponseHandler- этой
sendMessageрезультат вызоваhandleMessageinresponseHandler.- получить атрибуты из
Messageи обработать его, обновить UIпример кода:
/* 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-и-зачем-ты-должен-быть-через-них-в-ваш-андроид-приложения
- получить экземпляр обработчика потока пользовательского интерфейса и использовать
handler.sendMessage();- вызов
post()методhandler.post();runOnUiThread()view.post()
можно использовать
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вы должны показать тост.
Я сделал этот подход на основе ответа 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(); } }); }работал хорошо для меня.
я столкнулся с той же проблемой:
E/AndroidRuntime: FATAL EXCEPTION: Thread-4 Process: com.example.languoguang.welcomeapp, PID: 4724 java.lang.RuntimeException: Can't toast on a thread that has not called Looper.prepare() at android.widget.Toast$TN.<init>(Toast.java:393) at android.widget.Toast.<init>(Toast.java:117) at android.widget.Toast.makeText(Toast.java:280) at android.widget.Toast.makeText(Toast.java:270) at com.example.languoguang.welcomeapp.MainActivity.run(MainActivity.java:51) at java.lang.Thread.run(Thread.java:764) I/Process: Sending signal. PID: 4724 SIG: 9 Application terminated.перед: функция onCreate
Thread thread = new Thread(new Runnable() { @Override public void run() { Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show(); } }); thread.start();после: функция onCreate
runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show(); } });это сработало.
Comments