Androidでバックグラウンドスレッドからトーストをどのように表示しますか?


回答:


246

あなたのスレッドからActivityrunOnUiThreadメソッドを呼び出すことでそれを行うことができます:

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

これを行う方法を理解しているのかわかりません。私は既存のpublic void run()を持っています。そこにこのコードを入れてみました。うまくいかなかったので正しくないのはわかっていますが、本当に行き詰まっています。
SwimBikeRun 2012年

14
「アクティビティ」はコンストラクタで非UIスレッドに渡されますか?別のスレッド内から使用しているアクティビティオブジェクトを取得する正しい方法は何ですか?
snapfractalpop 2012年

設定しThreadへのオブジェクトの参照をActivityしてActivityonResume。設定を解除し、その中ActivityonPause。とを尊重するsynchronizedロックの下で両方を実行します。ActivityThread
JohnnyLambada 2012

5
Activityインスタンスにアクセスできない場合があります。代わりに単純なヘルパークラスを使用できます

5
私は通常MyActivity.this.runOnUiThread()、それがインナーThread/ 内からうまく機能することを発見しましたAsyncTask
アンソニーアトキンソン

61

私は自分のアクティビティに呼び出され、showToastどこからでも呼び出せるメソッドが欲しい...

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

その後、私は最も頻繁にそれをMyActivityこのような任意のスレッド内から呼び出します...

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

3
おかげで、私はこのほとんどの活動を今追加しています。
Gene Myers、

1
TOASTの場合は、アクティビティコンテキストではなく、常にアプリケーションコンテキストを使用してください。
Yousha Aleayoub

1
@YoushaAleayoubなんで?
OneWorld

1
@OneWorld、証明:1-トーストメッセージの場合、Google Dev Guideはアプリケーションコンテキストを使用し、それを使用することを明示的に伝えます。2- stackoverflow.com/a/4128799/1429432 3- stackoverflow.com/a/10347346/1429432 4- groups.google.com/d/msg/android-developers/3i8M6-wAIwM/...
Yousha Aleayoub

@YoushaAleayoubあなたが提供したリンクには多くの議論と推測があります。たとえば、RomainGuyは、証明にメモリリークはないと言っています。4.一部のリンクは2009年のAndroidの初期のものです。また、他のリンクでは、両方のコンテキストを使用できると人々が言っ​​ています。アクティビティとアプリケーション。多分あなたはより最新の本当の証拠に基づく証明を持っていますか?1のリンクはありますか?
OneWorld、2016

28

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

あなたが持っているコンテキストが完全な答えである活動ではないとき。どうもありがとう!
フランカ

17

Activityor がない場所を含む、ほとんどどこからでも機能する1つのアプローチViewHandler、メインスレッドにa を取得してトーストを表示することです。

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

このアプローチの利点はContextServiceおよびを含むすべてので機能することApplicationです。


10

同様に、このまたはこれ、と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();
}

6

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

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

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

解決:

  1. HandlerThreadを作成するを開始する
  2. からルーパーを使用してハンドラーを作成します。HandlerThreadrequestHandler
  3. メインスレッドからルーパーを使用してハンドラーを作成し、 responseHandlerオーバーライドします。handleMessageメソッドする
  4. post上のRunnableタスクrequestHandler
  5. 内部Runnableタスク、呼び出しsendMessageresponseHandler
  6. このsendMessage結果、handleMessageinが呼び出されresponseHandlerます。
  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);
    }

役立つ記事:

ハンドラースレッドと、なぜあなたは自分のAndroidアプリでそれらを使用する必要がありますか

android-looper-handler-handlerthread-i


5
  1. UIスレッドハンドラーのインスタンスを取得して使用する handler.sendMessage();
  2. post()メソッドを呼び出すhandler.post();
  3. runOnUiThread()
  4. view.post()

3

メッセージの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場合があります。


2

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

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


0

同じ問題が発生しました:

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

出来た。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.