Android:在线程中敬酒

时间:2010-06-28 17:31:49

标签: android multithreading android-toast

如何从线程中显示Toast条消息?

11 个答案:

答案 0 :(得分:237)

您可以通过从线程中调用Activity的{​​{1}}方法来执行此操作:

runOnUiThread

答案 1 :(得分:58)

我喜欢在我的活动中使用名为showToast的方法,我可以从任何地方拨打电话......

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

然后,我经常在MyActivity内的任何线程上调用它...

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

答案 2 :(得分:26)

这与其他答案类似,但是针对新的可用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();
            }
        });
    }
}

答案 3 :(得分:11)

从几乎任何地方开始工作的一种方法,包括从没有ActivityView的地方开始,就是抓住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,包括ServiceApplication

答案 4 :(得分:10)

thisthis一样,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();
}

答案 5 :(得分:6)

有时,您必须从另一个Thread向UI线程发送消息。当您无法在UI线程上执行网络/ IO操作时,会发生这种情况。

下面的示例处理该场景。

  1. 您有UI线程
  2. 您必须启动IO操作,因此无法在UI线程上运行Runnable。因此,将Runnable发布到HandlerThread
  3. 上的处理程序
  4. Runnable获取结果并将其发送回UI线程并显示Toast消息。
  5. 解决方案:

    1. 创建HandlerThread并启动它
    2. 使用HandlerThread中的Handler创建LooperrequestHandler
    3. 使用主线程中的Looper创建一个处理程序:responseHandler并覆盖handleMessage方法
    4. {li> post Runnable 上的requestHandler任务
    5. Runnable内部任务,请致电sendMessage
    6. 上的responseHandler
    7. sendMessage handleMessage responseHandler Message /* 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); } 次结果调用。{/ 1}
    8. [warn] s.b.DatabaseConfig - Use `profile` instead of `driver`. The latter is deprecated since Slick 3.2 and will be removed. 获取属性并对其进行处理,更新用户界面
    9. 示例代码:

      slick.dbs.default.driver = "slick.driver.MySQLDriver$"
      slick.dbs.default.db.driver = "com.mysql.jdbc.Driver"
      slick.dbs.default.db.url = "jdbc:mysql://"
      slick.dbs.default.db.user = ""
      slick.dbs.default.db.password = ""
      

      有用的文章:

      handlerthreads-and-why-you-should-be-using-them-in-your-android-apps

      android-looper-handler-handlerthread-i

答案 6 :(得分:5)

  1. 获取UI线程处理程序实例并使用handler.sendMessage();
  2. 致电post()方法handler.post();
  3. runOnUiThread()
  4. view.post()

答案 7 :(得分:3)

您可以使用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获取。

答案 8 :(得分:2)

我根据mjaggard回答:

制作了这种方法
dy

对我来说很好。

答案 9 :(得分:1)

带有runOnUiThread的Kotlin代码

runOnUiThread(
        object : Runnable {
            override fun run() {
                Toast.makeText(applicationContext, "Calling from runOnUiThread()", Toast.LENGTH_SHORT)  
            }
        }
)

答案 10 :(得分: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();
    }
});

它有效。