Android:在线程中吐司

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3134683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:51:34  来源:igfitidea点击:

Android: Toast in a thread

androidmultithreadingandroid-toast

提问by Arutha

How can I display Toastmessages from a thread?

如何显示来自线程的Toast消息?

回答by Lauri Lehtinen

You can do it by calling an Activity's runOnUiThreadmethod from your thread:

您可以通过从您的线程调用 anActivityrunOnUiThread方法来做到这一点:

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

回答by mjaggard

I like to have a method in my activity called showToastwhich I can call from anywhere...

我喜欢在我的活动中调用一个方法showToast,我可以从任何地方调用它...

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

I then most frequently call it from within MyActivityon any thread like this...

然后我最常在MyActivity这样的任何线程上从内部调用它......

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

回答by ChrisCM

This is similar to other answers, however updated for new available apis and much cleaner. Also, does not assume you're in an Activity Context.

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

回答by Mike Laren

One approach that works from pretty much anywhere, including from places where you don't have an Activityor View, is to grab a Handlerto the main thread and show the toast:

一种适用于几乎任何地方的方法,包括从没有Activityor 的地方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();
    }
  });
}

The advantage of this approach is that it works with any Context, including Serviceand Application.

这种方法的优点是它适用于任何Context,包括ServiceApplication

回答by yanchenko

Like thisor this, with a Runnablethat shows the Toast. Namely,

这样这样,用一个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();
}

回答by Ravindra babu

Sometimes, you have to send message from another Threadto UI thread. This type of scenario occurs when you can't execute Network/IO operations on UI thread.

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

Below example handles that scenario.

下面的示例处理这种情况。

  1. You have UI Thread
  2. You have to start IO operation and hence you can't run Runnableon UI thread. So post your Runnableto handler on HandlerThread
  3. Get the result from Runnableand send it back to UI thread and show a Toastmessage.
  1. 你有 UI 线程
  2. 您必须启动 IO 操作,因此您无法Runnable在 UI 线程上运行。所以把你Runnable的处理程序发布到HandlerThread
  3. 从中获取结果Runnable并将其发送回 UI 线程并显示一条Toast消息。

Solution:

解决方案:

  1. Create a HandlerThreadand start it
  2. Create a Handlerwith Looperfrom HandlerThread:requestHandler
  3. Create a Handler with Looper from Main Thread: responseHandlerand override handleMessagemethod
  4. posta Runnabletask on requestHandler
  5. Inside Runnabletask, call sendMessageon responseHandler
  6. This sendMessageresult invocation of handleMessagein responseHandler.
  7. Get attributes from the Messageand process it, update UI
  1. 创建一个HandlerThread并启动它
  2. 使用Looper从以下位置创建处理程序HandlerThreadrequestHandler
  3. 从主线程使用 Looper 创建一个处理程序: responseHandler并覆盖handleMessage方法
  4. post一项Runnable任务requestHandler
  5. 里面Runnable的任务,呼吁sendMessageresponseHandler
  6. 这个sendMessage结果调用handleMessagein responseHandler
  7. 从中获取属性Message并处理它,更新 UI

Sample code:

示例代码:

    /* 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);
    }

Useful articles:

有用的文章:

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

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

android-looper-handler-handlerthread-i

android-looper-handler-handlerthread-i

回答by Kerwin You

  1. Get UI Thread Handler instance and use handler.sendMessage();
  2. Call post()method handler.post();
  3. runOnUiThread()
  4. view.post()
  1. 获取 UI Thread Handler 实例并使用 handler.sendMessage();
  2. 调用post()方法handler.post();
  3. runOnUiThread()
  4. view.post()

回答by Vinoj John Hosan

You can use Looperto send Toastmessage. Go through this linkfor more details.

您可以使用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();
}

and it is called in your thread. Context may be Activity.getContext()getting from the Activityyou have to show the toast.

它在您的线程中被调用。上下文可能Activity.getContext()来自Activity您必须展示的祝酒词。

回答by ?ngelo Polotto

I made this approach based on mjaggard answer:

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

Worked well for me.

对我来说效果很好。

回答by Languoguang

I encountered the same problem:

我遇到了同样的问题:

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.run(MainActivity.java:51)
                  at java.lang.Thread.run(Thread.java:764)
I/Process: Sending signal. PID: 4724 SIG: 9
Application terminated.

Before: onCreate function

之前:onCreate 函数

Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show();
    }
});
thread.start();

After: onCreate function

之后:onCreate 函数

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(getBaseContext(), "Thread", Toast.LENGTH_LONG).show();
    }
});

it worked.

有效。