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(() -> 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();
}
});
}
}
Activity
またはView
がない場所など、ほとんどどこからでも機能する1つのアプローチは、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
で動作することです。
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();
}
時には、別のThread
からUIスレッドにメッセージを送信する必要があります。このタイプのシナリオは、UIスレッドでネットワーク/ IO操作を実行できない場合に発生します。
以下の例はそのシナリオを処理します。
Runnable
を実行できません。 Runnable
をHandlerThread
のハンドラーに投稿してくださいRunnable
から結果を取得してUIスレッドに送り返し、Toast
メッセージを表示します。解決:
HandlerThread
:requestHandler
から Looper で Handler を作成しますresponseHandler
およびhandleMessage
メソッドをオーバーライドしますpost
a Runnable
requestHandler
のタスクRunnable
タスク内で、sendMessage
でresponseHandler
を呼び出しますsendMessage
は、handleMessage
でresponseHandler
を呼び出します。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-and-why-you-should-be-using-them-in-your-Android-apps
handler.sendMessage();
を使用しますpost()
メソッドを呼び出すhandler.post();
runOnUiThread()
view.post()
Looper
を使用してToast
メッセージを送信できます。詳細については、こちらをご覧ください link .
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$1.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();
}
});
動いた。