Toast "отправляет сообщение обработчику по мертвой теме"

Я пытаюсь показать простое сообщение через Toast, и я получаю исключение RunTime Exception, отправляя сообщение обработчику в мертвом потоке. Класс, который пытается показать сообщение Toast, расширяет IntentService. Класс (C2DMReceiver) фактически исходит из примера ChromeToPhone для C2DM. Вот способ:

/** * 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 "отправляет сообщение обработчику по мертвой теме""

Это связано с ошибкой в ​​AsyncTask в платформе Android. AsyncTask.java имеет следующий код:

 private static final InternalHandler sHandler = new InternalHandler(); 

Он ожидает, что это будет инициализировано в основном потоке, но это не гарантируется, так как оно будет инициализировано в зависимости от того, какой поток произошел, чтобы заставить класс запускать свои статические инициализаторы. Я воспроизвел эту проблему, когда обработчик ссылается на рабочий поток.

Общим примером, который вызывает это, является использование класса IntentService. Код примера C2DM делает это.

Простым обходным решением является добавление следующего кода в метод onCreate приложения:

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

Это заставит AsyncTask инициализироваться в основном потоке. Я зарегистрировал ошибку об этом в базе данных ошибок Android. См. 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(); } }); } } 

Другой способ выполнения сообщений обжарки в основном потоке из фона – использовать для этого небольшой метод полезности. Хитрость заключается в создании обработчика, который прикреплен к петлевому механизму основного потока (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(); } }); } } 

Вы должны отображать тост из основного потока или он не будет отображаться на экране. Обработчик выполняется из потока, в котором он был создан. Если вы создаете обработчик в onCreate вашего intenservice, он должен работать так, как планировалось, когда вы отправляете свое сообщение.

Метод onMessage не был вызван в главной теме.

Поэтому вам нужно создать нового обработчика.

Применить этот код:

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

Это должно работать нормально