2

I am facing some problems when I'm using Toast inside run method of Thread class.

My error Logcat

09-16 11:42:38.140: E/AndroidRuntime(1446): in writeCrashedAppName, pkgName :com.monday.worker_android
09-16 11:59:17.920: E/AndroidRuntime(2144): FATAL EXCEPTION: AsyncTask #1
09-16 11:59:17.920: E/AndroidRuntime(2144): java.lang.RuntimeException: An error occured while executing doInBackground()
09-16 11:59:17.920: E/AndroidRuntime(2144):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
09-16 11:59:17.920: E/AndroidRuntime(2144):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
09-16 11:59:17.920: E/AndroidRuntime(2144):     at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
09-16 11:59:17.920: E/AndroidRuntime(2144):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
09-16 11:59:17.920: E/AndroidRuntime(2144):     at java.util.concurrent.FutureTask.run(FutureTask.java:138)
09-16 11:59:17.920: E/AndroidRuntime(2144):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
09-16 11:59:17.920: E/AndroidRuntime(2144):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
09-16 11:59:17.920: E/AndroidRuntime(2144):     at java.lang.Thread.run(Thread.java:1019)
09-16 11:59:17.920: E/AndroidRuntime(2144): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
09-16 11:59:17.920: E/AndroidRuntime(2144):     at android.os.Handler.<init>(Handler.java:121)
09-16 11:59:17.920: E/AndroidRuntime(2144):     at android.widget.Toast.<init>(Toast.java:75)
09-16 11:59:17.920: E/AndroidRuntime(2144):     at android.widget.Toast.makeText(Toast.java:244)
09-16 11:59:17.920: E/AndroidRuntime(2144):     at com.monday.worker_android.SwipePage$2.doInBackground(SwipePage.java:142)
09-16 11:59:17.920: E/AndroidRuntime(2144):     at com.monday.worker_android.SwipePage$2.doInBackground(SwipePage.java:1)
09-16 11:59:17.920: E/AndroidRuntime(2144):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
09-16 11:59:17.920: E/AndroidRuntime(2144):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)

But when I ignore Toast it works fine. But I want to use it. Please help.

4

7 回答 7

9

通过从您的 Thread 调用 Activity 的runOnUiThread方法:

activity.runOnUiThread(new Runnable() {
    public void run() {
        Toast.makeText(activity, "Toast message inside Thread", Toast.LENGTH_LONG).show();
    }
});
于 2013-09-16T06:55:22.670 回答
3

您必须在 UI 线程上调用 Toast。

AsyncTask onPostExecute 在 UI 线程上运行。如果你想“强制”一个 UI 线程,你可以在 onBackground 中使用下面的代码:

// code runs in a thread
   runOnUiThread(new Runnable() {
      @Override
          public void run() {
              Toast.makeText(....).show();
          }
   });
于 2013-09-16T06:56:06.813 回答
1

您不能在非 UI 线程中使用或访问任何 UI 元素。如果您想查看有关您的线程的一些消息,那么您可以使用 AsyncTask 并使用 preExecute 方法中的 UI 内容。因为 AsyncTask 的 pre 和 postExecute 是在 UI 线程上运行的。

如果您想这样做,请参阅Problem with Toast in AsyncTask method call

如果您要排除一种小而简单的方法,则只需使用 LOG 类,例如:

Log.d("String Key", "the value you want to see");

如果您想了解有关日志的一些想法,请参阅Android Log.v()、Log.d()、Log.i()、Log.w()、Log.e() - 何时使用每一个?

希望这些足以解决您的问题。

于 2013-09-16T06:59:46.123 回答
1

你不能在 Thread 中打印 Toast,因为 Thread 是在后台运行的,它不会影响 GUI 的东西。您必须使用 UI 线程来完成。

runOnUiThread(new Runnable() {
      @Override
          public void run() {
             Toast.makeText(this, "YOUR MESSAGE TO PRINT", Toast.LENGTH_LONG).show().
          }
   });
于 2013-09-16T07:00:58.670 回答
1

根据您的说法,您logcat正在尝试更新其中无法直接UI part (using Toast)更新的doInBackground()内容AsyncTask

使用相同的onPostExecute()用于handling/updating UI Part

如果你想显示 Toast in doInbackground() wrapToast in runOnUIThread()但这不是最好的解决方案。

喜欢

runOnUiThread(new Runnable() {
      @Override
          public void run() {
              // Show Toast Here
          }
   });
于 2013-09-16T06:56:01.763 回答
1

您可以如下显示您的 Toast 消息:

YourActivityName.this.runOnUiThread(new Runnable() {

        @Override
        public void run() {
            Toast.makeText(YourActivityName.this, "This is Toast!!!", Toast.LENGTH_SHORT).show();

        }
    });
于 2013-09-16T06:56:40.510 回答
0

您需要在方法内部调用onPostExecute()toast

@Override
protected void onPostExecute(Boolean result)
{
    super.onPostExecute(result);
    Toast.makeText(context, "Message", Toast.LENGTH_SHORT).show();
}
于 2013-09-16T06:57:39.030 回答