Toast“发送消息到一个死线程上的Handler”

我试图通过吐司显示一个简单的消息,并得到一个RunTimeexception“发送消息到一个死线程上的处理程序”。 试图显示Toast消息的类扩展了IntentService。 该类(C2DMReceiver)实际上来自C2DM的ChromeToPhone示例。 这里是方法:

/** * Called when a cloud message has been received. */ @Override public void onMessage(Context context, Intent intent) { Log.i(LOG_TAG, "A message notification has occured with the cloud."); Log.i(LOG_TAG, "Showing toast message of the broadcast..."); Toast toast = Toast.makeText(context, "Some text", Toast.LENGTH_LONG); toast.show(); Log.i(LOG_TAG, "Sending notification of the broadcast..."); LauncherUtils.generateNotification(this, "this is where the text would go.", "Broadcast", intent); } } 

我假定,因为类扩展了IntentService,所以可以用这种方式从这里请求一个简单的Toast消息。 这不正确吗?

Solutions Collecting From Web of "Toast“发送消息到一个死线程上的Handler”"

这是由于Android框架中的AsyncTask中的一个错误。 AsyncTask.java有以下代码:

 private static final InternalHandler sHandler = new InternalHandler(); 

它期望这在主线程上被初始化,但是不能保证,因为它将被初始化在哪个线程发生,导致类运行它的静态初始值设定项。 我在Handler引用一个工作线程的时候重现了这个问题。

导致这种情况的常见模式是使用IntentService类。 C2DM示例代码执行此操作。

一个简单的解决方法是将下面的代码添加到应用程序的onCreate方法中:

 Class.forName("android.os.AsyncTask"); 

这将强制AsyncTask在主线程中初始化。 我在android bug数据库中提出了一个错误。 请参阅http://code.google.com/p/android/issues/detail?id=20915

 public class NetworkService extends IntentService { Handler mMainThreadHandler = null; public NetworkService() { super(NetworkService.class.getName()); mMainThreadHandler = new Handler(); } @Override protected void onHandleIntent(Intent arg) { System.out.printf("Network service intent handling: %s\n", arg.toString()); mMainThreadHandler.post(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), "BusyBox updated", Toast.LENGTH_LONG).show(); } }); } } 

在主线程中完成从后台烘烤消息的另一种方法是使用一个小的实用程序方法。 诀窍是创build一个附加到主线程的Looper(Looper.getMainLooper())的处理程序。

 public class ToastUtils { public static void showToastInUiThread(final Context ctx, final int stringRes) { Handler mainThread = new Handler(Looper.getMainLooper()); mainThread.post(new Runnable() { @Override public void run() { Toast.makeText(ctx, ctx.getString(stringRes), Toast.LENGTH_SHORT).show(); } }); } } 

您必须从主线显示敬酒,否则将不会显示在屏幕上。 处理程序从它创build的线程执行。如果在intentservice的onCreate中创build处理程序,它应该在发送消息时按预期工作。

主线程上未调用onMessage方法。

所以你需要做一个新的Handler。

应用此代码:

 public class GCMIntentService extends GCMBaseIntentService { Handler handler; public GCMIntentService() { handler = new Handler(); } } 

你可以像这样在ui线程上运行你的代码:

 runOnUiThread(new Runnable() { public void run() { try { //YOUR CODE } catch (Exception e) { Log.d(TAG, e.getMessage()); } } }); 

这应该工作得很好