Ясность на IntentService

У меня есть этот сервис, который расширяет IntentService.

public class RefreshService extends IntentService {

static final String TAG = "RefreshService";

public RefreshService() {
    super(TAG);
}

@Override
public void onCreate() {
    super.onCreate();
    Log.d(TAG, "onCreated");
}



@Override
public void onDestroy() {
    super.onDestroy();
    Log.d(TAG, "onDestroyed");
}

@Override
public IBinder onBind(Intent intent) {
    return  null;
}

@Override
protected void onHandleIntent(Intent intent) {

    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    final String username = prefs.getString("username", "").trim();
    final String password = prefs.getString("password", "").trim();

    Log.d(TAG, "onDestroyeds");

    if (TextUtils.isEmpty(username) || (TextUtils.isEmpty(password))){
        Toast.makeText(this, "Please update your username and password", Toast.LENGTH_LONG ).show();
        return;
    }

   // here code for fetching data and inserting into db.

}

}

Когда настройки отсутствуют, вместо показа всплывающего сообщения я получаю следующую ошибку.

 07-12 18:28:33.125    2961-2961/com.example.krishna.yamba I/menu_item_selected﹕ [0,Refresh]
07-12 18:28:33.143    2961-2961/com.example.krishna.yamba D/RefreshService﹕ onCreated
07-12 18:28:33.147    2961-3637/com.example.krishna.yamba D/RefreshService﹕ onDestroyeds
07-12 18:28:33.147    2961-3637/com.example.krishna.yamba D/RefreshService﹕ onDestroyeds
07-12 18:28:33.181    2961-2961/com.example.krishna.yamba D/RefreshService﹕ onDestroyed
07-12 18:28:33.197    2961-3637/com.example.krishna.yamba W/MessageQueue﹕ Handler (android.view.ViewRootImpl$ViewRootHandler) {38f6505f} sending message to a Handler on a dead thread
    java.lang.IllegalStateException: Handler (android.view.ViewRootImpl$ViewRootHandler) {38f6505f} sending message to a Handler on a dead thread
            at android.os.MessageQueue.enqueueMessage(MessageQueue.java:325)
            at android.os.Handler.enqueueMessage(Handler.java:631)
            at android.os.Handler.sendMessageAtTime(Handler.java:600)
            at android.os.Handler.sendMessageDelayed(Handler.java:570)
            at android.os.Handler.post(Handler.java:326)
            at android.view.ViewRootImpl.loadSystemProperties(ViewRootImpl.java:5413)
            at android.view.ViewRootImpl.<init>(ViewRootImpl.java:378)
            at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:253)
            at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
            at android.widget.Toast$TN.handleShow(Toast.java:414)
            at android.widget.Toast$TN$1.run(Toast.java:322)
            at android.os.Handler.handleCallback(Handler.java:738)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.os.HandlerThread.run(HandlerThread.java:61)

Я предполагаю, что следующее верно

  1. Код в методе onHandleIntent выполняется в другом потоке.
  2. Поэтому здесь хорошо выполнять интенсивные задачи. (в этом случае я просто загружаю и обновляю базу данных)

Когда настройки верны, все работает нормально. Тогда добавление всплывающего сообщения по сравнению со сборкой и обновлением не должно быть проблемой, верно?

Как поставить тостовое сообщение при пустых настройках?

2 ответа

Решение

IntentService выполняет его onHandleIntent в отдельном потоке. С другой стороны, Toast работает в основном потоке пользовательского интерфейса. Для того, чтобы показать Toast в IntentService, вам нужно сделать что-то вроде этого:

new Handler(Looper.getMainLooper()).post(new Runnable() {           
    @Override
    public void run() {
        Toast.makeText(RefreshService.this, "Toast msg here", Toast.LENGTH_LONG).show();
    }
});

Код в методе onHandleIntent выполняется в другом потоке.

Правильный.

Поэтому здесь хорошо выполнять интенсивные задачи. (в этом случае я просто загружаю и обновляю базу данных)

Правильный.

Тогда добавление всплывающего сообщения по сравнению со сборкой и обновлением не должно быть проблемой, верно?

Нет, потому что вы не можете поднять Toast из фоновой темы. Это, по сути, то, что ошибка говорит вам.

Как поставить тостовое сообщение при пустых настройках?

Правильный ответ - не использовать Toast, Это второе худшее решение для сообщения пользователю о состоянии ошибки (самое худшее - просто не пытаться сообщить пользователю вообще). Нет никакой гарантии, что пользователь будет смотреть на экран в тот момент, когда Toast читается, и поэтому пользователь может пропустить сообщение. Используйте гренки или что-то в этом роде.

В любом случае, вам нужно договориться, чтобы основной поток приложения как-то обновлял пользовательский интерфейс... если ваш пользовательский интерфейс находится на переднем плане. Современные решения для этого обычно включают в себя какую-то шину событий. В настоящее время существует три основных реализации шины событий:

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

Другие вопросы по тегам