Android:在线程中吐司
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3134683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android: Toast in a thread
回答by Lauri Lehtinen
You can do it by calling an Activity
's runOnUiThread
method from your thread:
您可以通过从您的线程调用 anActivity
的runOnUiThread
方法来做到这一点:
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
}
});
回答by mjaggard
I like to have a method in my activity called showToast
which I can call from anywhere...
我喜欢在我的活动中调用一个方法showToast
,我可以从任何地方调用它...
public void showToast(final String toast)
{
runOnUiThread(() -> Toast.makeText(MyActivity.this, toast, Toast.LENGTH_SHORT).show());
}
I then most frequently call it from within MyActivity
on any thread like this...
然后我最常在MyActivity
这样的任何线程上从内部调用它......
showToast(getString(R.string.MyMessage));
回答by ChrisCM
This is similar to other answers, however updated for new available apis and much cleaner. Also, does not assume you're in an Activity Context.
这与其他答案类似,但是针对新的可用 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();
}
});
}
}
回答by Mike Laren
One approach that works from pretty much anywhere, including from places where you don't have an Activity
or View
, is to grab a Handler
to the main thread and show the toast:
一种适用于几乎任何地方的方法,包括从没有Activity
or 的地方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();
}
});
}
The advantage of this approach is that it works with any Context
, including Service
and Application
.
这种方法的优点是它适用于任何Context
,包括Service
和Application
。
回答by yanchenko
Like thisor this, with a Runnable
that shows the Toast
.
Namely,
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();
}
回答by Ravindra babu
Sometimes, you have to send message from another Thread
to UI thread. This type of scenario occurs when you can't execute Network/IO operations on UI thread.
有时,您必须从另一个Thread
线程向 UI 线程发送消息。当您无法在 UI 线程上执行网络/IO 操作时,就会发生这种情况。
Below example handles that scenario.
下面的示例处理这种情况。
- You have UI Thread
- You have to start IO operation and hence you can't run
Runnable
on UI thread. So post yourRunnable
to handler onHandlerThread
- Get the result from
Runnable
and send it back to UI thread and show aToast
message.
- 你有 UI 线程
- 您必须启动 IO 操作,因此您无法
Runnable
在 UI 线程上运行。所以把你Runnable
的处理程序发布到HandlerThread
- 从中获取结果
Runnable
并将其发送回 UI 线程并显示一条Toast
消息。
Solution:
解决方案:
- Create a HandlerThreadand start it
- Create a Handlerwith Looperfrom
HandlerThread
:requestHandler
- Create a Handler with Looper from Main Thread:
responseHandler
and overridehandleMessage
method post
aRunnable
task onrequestHandler
- Inside
Runnable
task, callsendMessage
onresponseHandler
- This
sendMessage
result invocation ofhandleMessage
inresponseHandler
. - Get attributes from the
Message
and process it, update UI
- 创建一个HandlerThread并启动它
- 使用Looper从以下位置创建处理程序:
HandlerThread
requestHandler
- 从主线程使用 Looper 创建一个处理程序:
responseHandler
并覆盖handleMessage
方法 post
一项Runnable
任务requestHandler
- 里面
Runnable
的任务,呼吁sendMessage
对responseHandler
- 这个
sendMessage
结果调用handleMessage
inresponseHandler
。 - 从中获取属性
Message
并处理它,更新 UI
Sample code:
示例代码:
/* 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);
}
Useful articles:
有用的文章:
handlerthreads-and-why-you-should-be-using-them-in-your-android-apps
handlerthreads-and-why-you-should-be-using-them-in-your-android-apps
回答by Kerwin You
- Get UI Thread Handler instance and use
handler.sendMessage();
- Call
post()
methodhandler.post();
runOnUiThread()
view.post()
- 获取 UI Thread Handler 实例并使用
handler.sendMessage();
- 调用
post()
方法handler.post();
runOnUiThread()
view.post()
回答by Vinoj John Hosan
You can use Looper
to send Toast
message. Go through this linkfor more details.
您可以使用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();
}
and it is called in your thread. Context may be Activity.getContext()
getting from the Activity
you have to show the toast.
它在您的线程中被调用。上下文可能Activity.getContext()
来自Activity
您必须展示的祝酒词。
回答by ?ngelo Polotto
I made this approach based on mjaggard answer:
我根据 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();
}
});
}
Worked well for me.
对我来说效果很好。
回答by Languoguang
I encountered the same problem:
我遇到了同样的问题:
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.
Before: onCreate function
之前:onCreate 函数
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show();
}
});
thread.start();
After: onCreate function
之后:onCreate 函数
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show();
}
});
it worked.
有效。