Тост в Android-фрагментах с нулевым указателем expn - PullRequest
0 голосов
/ 12 сентября 2018

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

Toast.makeText(getActivity(), "Connection Failure", Toast.LENGTH_LONG).show();

и мои журналы ST ниже.

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
   at android.widget.Toast.(Toast.java:103)
   at android.widget.Toast.makeText(Toast.java:256)

Ответы [ 6 ]

0 голосов
/ 22 июля 2019
if (isAdded()) {
    Toast.makeText(getActivity(), "something", Toast.LENGTH_SHORT).show();
}

или попробуйте это

if(getActivity() != null)
   Toast.makeText(getActivity(), "Connection Failure", Toast.LENGTH_LONG).show();

В моем случае оба будут работать нормально, потому что в некоторых случаях getActivity() вызывается при отсоединении фрагмента.

Так что мы должны позаботиться и об этом.

0 голосов
/ 12 сентября 2018

Согласно коду & javadoc для Fragment.getActivity() вы можете получить null возвращено:

/**
 * Return the {@link FragmentActivity} this fragment is currently associated with.
 * May return {@code null} if the fragment is associated with a {@link Context}
 * instead.
 *
 * @see #requireActivity()
 */
@Nullable
final public FragmentActivity getActivity() {
    return mHost == null ? null : (FragmentActivity) mHost.getActivity();
}

Особенно это может произойти, когда ваш фрагмент не привязан к действию (как указано здесь и здесь ).

Точно так же getContext() также может возвращать ноль.

Есть хорошее обсуждение того, когда они могут быть нулевыми, по этому возможно связанpost:


Простое решение уже было предоставлено - поставить нулевую проверку перед отображением Toast.

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


Лучшим решением было бы отсоединить вызов Retrofit от пользовательского интерфейса - поместить вызовы API вотдельный класс, который неt зависит от состояния пользовательского интерфейса .

. Используйте среду событий или pub-sub для связи из этого класса-оболочки API обратно с любыми компонентами пользовательского интерфейса, которым необходимо знать, когда возвращается вызов API.

EventBus или RxJava будут 2 общими решениями для этого (LocalBroadcastManager будет менее распространенным подходом).

Это позволит любому коду вызывать ваш API и подписываться на уведомление, когда API вернется.

Он также позволяет сохранять ответы API в (например) локальной базе данных, и в этом случае вы можете просто полагаться на шаблон LiveData для обновления любого необходимого пользовательского интерфейса.

Вот статья среднего уровня, в которой дается краткое описание того, как использовать компоненты архитектуры Android таким образом, используя шаблон Repository.


Учитывая, что некоторыепроекты не могут быть немедленно переработаны, может потребоваться обходной путь.

Упомянутый выше обходной путь проверки нуля полезен тем, что приложение больше не падает.К сожалению, это означает, что пользователь не будет предупрежден о неудачном вызове API.

Одной из альтернатив является создание собственного подкласса Application (многие проекты уже сделали это для инициализации общих библиотек) ипредоставить метод для статического доступа к этому приложению Context. (Аналогичное предложение впоследствии было сделано Кушалом.)

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

Представление вашего Application как одиночногобыло очень хорошо описано на этом посте:

0 голосов
/ 12 сентября 2018

Может быть getActivity() вызывается, когда фрагмент отсоединен. Попробуй.

if (isAdded()) {
    Toast.makeText(getActivity(), "something", Toast.LENGTH_SHORT).show();
}
0 голосов
/ 12 сентября 2018

Измените getActivity() на getContext().попробуйте следующий код:

Toast.makeText(getContext(), "Connection Failure", Toast.LENGTH_LONG).show();
0 голосов
/ 12 сентября 2018

Иногда getActivity () или getContext () могут генерировать исключение нулевого указателя, когда фрагмент не связан с Activity. Так что используйте метод onAttach

public class yourFragment extends Fragment {
   Context context

   @Override
   public void onAttach(Context context) {
        this.context = context;
        super.onAttach(context);
   }
}
0 голосов
/ 12 сентября 2018

Ваша активность context равна нулю в этой строке:

Toast.makeText(getActivity(), "Connection Failure", Toast.LENGTH_LONG).show();// getActivity() is null

Чтобы избежать сбоев, используйте это:

if(getActivity() != null)
   Toast.makeText(getActivity(), "Connection Failure", Toast.LENGTH_LONG).show();
...