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(() -> 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();
            }
        });
    }
}
    
像这样或者这样,用
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
到主线程并显示吐司:
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
。     
有时,您必须从另一个
Thread
向UI线程发送消息。当您无法在UI线程上执行网络/ IO操作时,会发生这种情况。 下面的示例处理该场景。 你有UI线程 您必须启动IO操作,因此无法在UI线程上运行
Runnable
。所以在
HandlerThread
上发布你的
Runnable
给处理程序 从
Runnable
获取结果并将其发送回UI线程并显示
Toast
消息。 解: 创建一个HandlerThread并启动它 从
HandlerThread
requestHandler
创建一个带Looper的处理程序 从主线程创建一个带有Looper的处理程序:
responseHandler
并覆盖
handleMessage
方法
post
requestHandler
上执行
Runnable
任务 在
Runnable
任务中,在
responseHandler
上拨打
sendMessage
这个
sendMessage
结果在
responseHandler
中调用了
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     
获取UI线程处理程序实例并使用
handler.sendMessage();
拨打
post()
方法
handler.post();
runOnUiThread()
view.post()
    
您可以使用
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
你必须展示吐司。     
我根据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();
    }
});
有效。     

要回复问题请先登录注册