Тосты никогда не очищаются, когда я обмениваю фрагменты

Я предоставляю отзывы пользователей с помощью Toast перед переключением фрагментов в своем приложении. Как только Toast появляется, он никогда не очищается. Выход из действия или уничтожение всего этого — единственный способ очистить тост.

Я попытался сохранить ссылку на Toast и вызвать cancel() после фиксации FragmentTransaction, но когда я это делаю, Toast вообще никогда не появляется.

Я добавил ведение журнала и уверен, что Toast отображается только один раз, а не в цикле или повторно. В противном случае приложение по-прежнему реагирует и не зависает. Когда я выхожу из приложения, Toast очищается благодаря функции cancel() в onStop().

public final class MyActivity extends SherlockFragmentActivity {

    Toast toast = null;

    //...

    @Override
    protected void onStop () {
        if (toast != null) toast.cancel();
        toast = null;
        super.onStop();
    }

    //...

    private final class MyServiceReceiver extends ResultReceiver {

        public MyServiceReceiver(Handler handler) {
            super(handler);
        }

        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            if (resultCode == MY_ERROR_CODE) {
                toast = Toast.makeText(getApplicationContext(), "my error message", Toast.LENGTH_SHORT);
                toast.show();

                FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
                ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out,
                            android.R.anim.fade_in, android.R.anim.fade_out);
                ft.replace(R.id.main_layout, new MyFragment());
                ft.commit();

                //if (toast != null) toast.cancel();
                //toast = null;
            }
        }

    }

}

person click_whir    schedule 01.06.2013    source источник


Ответы (2)


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

toast = Toast.makeText(это, "моё сообщение об ошибке", Toast.LENGTH_SHORT);

тост.шоу();

person Ethan    schedule 01.06.2013
comment
Я думал желательно привязываться к контексту приложения? Поскольку действие может завершиться после предъявления тоста. this не является Activity, так как этот Toast отображается в классе ResultReceiver. Я попытался переместить содержимое ResultReciever в другой метод, где я мог бы получить доступ к this, но результат тот же. Тост появляется и никогда не уходит. - person click_whir; 02.06.2013
comment
Я вижу, что Toast находится в вашем внутреннем классе MyServiceReceiver, вам не нужно перемещать свой код, чтобы использовать его, можно использовать Toast.makeText(MyActivity.this, мое сообщение об ошибке, Toast.LENGTH_SHORT).show(). Что еще более важно, убедитесь, что ваш тост не вызывается несколько раз. Дайте мне знать, если это работает для вас. - person Ethan; 02.06.2013
comment
Спасибо, мне еще нужно кое-что узнать о Java. Использование контекста Activity по-прежнему не устраняет проблему. ResultReceiver вызывается из IntentService, поэтому находится в потоке, отличном от пользовательского интерфейса, и Теперь я вижу, что всплывающие уведомления должны создаваться из потока пользовательского интерфейса. - person click_whir; 03.06.2013

Проблема здесь в том, что IntentService вызывает ResultReceiver, поэтому Toast создается из потока пользовательского интерфейса. см. этот пост.

Чтобы решить эту проблему, я создаю обработчик для действия и делаю там тосты. В качестве бонуса мне не нужно управлять ссылкой на Toast и очищать Activity.onStop.

person click_whir    schedule 03.06.2013