Android:在一个线程中吐司
如何显示来自线程的Toast消息?
你可以通过从你的线程中调用一个Activity
的runOnUiThread
方法来实现:
activity.runOnUiThread(new Runnable() { public void run() { Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show(); } });
我喜欢在我的活动中有一个名为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));
这是类似的其他答案,但更新为新的可用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(); } }); } }
像这个或这个 ,用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
地方,都可以使用一种方法,即将Handler
主线程并显示Toast:
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
。
- 获取UI线程处理程序实例并使用
handler.sendMessage();
- 调用
post()
方法handler.post();
-
runOnUiThread()
-
view.post()
有时,你必须从另一个Thread
发送消息到UI线程。 当您无法在UI线程上执行networking/ IO操作时,就会出现这种情况。
以下示例处理该场景。
- 你有UI线程
- 您必须启动IO操作,因此您无法在UI线程上运行
Runnable
。 所以发布你的Runnable
处理HandlerThread
- 从
Runnable
获取结果并将其发送回UI线程并显示Toast
消息。
解:
- 创build一个HandlerThread并启动它
- 使用
HandlerThread
:requestHandler
从Looper创build一个Handler - 使用主线程的
handleMessage
创build一个处理程序:responseHandler
并重写handleMessage
方法 - 在
requestHandler
上post
一个Runnable
任务 - 在
Runnable
任务中,调用responseHandler
sendMessage
- 这个
sendMessage
结果调用了handleMessage
中的handleMessage
。 - 从
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和-为什么-你-应该待使用了他们,在你的Android的应用程序
Android的尺蠖处理程序,handlerthread-I
您可以使用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
得到你要显示的toast。