web-dev-qa-db-ja.com

Android:スレッドでトースト

Toast スレッドからのメッセージを表示するにはどうすればよいですか?

107
Arutha

それを行うには、スレッドからActivityrunOnUiThreadメソッドを呼び出します。

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

アクティビティにshowToastというメソッドがあり、どこからでも呼び出すことができます...

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

次に、このようなスレッドでMyActivity内から最も頻繁に呼び出します...

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

これは他の回答と似ていますが、利用可能な新しい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();
            }
        });
    }
}
26
ChrisCM

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で動作することです。

13
Mike Laren

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();
}
10
yanchenko

時には、別のThreadからUIスレッドにメッセージを送信する必要があります。このタイプのシナリオは、UIスレッドでネットワーク/ IO操作を実行できない場合に発生します。

以下の例はそのシナリオを処理します。

  1. UIスレッドがあります
  2. IO操作を開始する必要があるため、UIスレッドでRunnableを実行できません。 RunnableHandlerThreadのハンドラーに投稿してください
  3. Runnableから結果を取得してUIスレッドに送り返し、Toastメッセージを表示します。

解決:

  1. HandlerThread を作成して開始する
  2. HandlerThreadrequestHandlerから LooperHandler を作成します
  3. メインスレッドからルーパーを使用してハンドラーを作成します:responseHandlerおよびhandleMessageメソッドをオーバーライドします
  4. post a RunnablerequestHandlerのタスク
  5. Runnableタスク内で、sendMessageresponseHandlerを呼び出します
  6. このsendMessageは、handleMessageresponseHandlerを呼び出します。
  7. 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

Android-looper-handler-handlerthread-i

6
Ravindra babu
  1. UIスレッドハンドラーインスタンスを取得し、handler.sendMessage();を使用します
  2. post()メソッドを呼び出すhandler.post();
  3. runOnUiThread()
  4. view.post()
5
Kerwin You

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から取得できます。トーストを表示する必要があります。

3

私は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();
        }
    });
}

私にとってはうまくいきました。

2
Ângelo Polotto

私は同じ問題に遭遇しました:

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();
    }
});

動いた。

0
Languoguang