Быстрая смена приложения Bottom Navigation вылетает
У меня есть Bottom Navigation с фрагментом и Retrofit для вызова API
Я звоню loadFragment
для переключения фрагментов, как показано ниже
private boolean loadFragment(Fragment fragment) {
//switching fragment
if (fragment != null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, fragment)
.commit();
return true;
}
return false;
}
Проблема в том, что мое приложение зависает, если я начинаю случайно щелкать и быстро менять фрагмент, когда я проверяю logcat, он показывает NPE при настройке некоторых данных.
Мой фрагмент состоит из следующих методов
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_current, container, false);
unbinder = ButterKnife.bind(this, view);
context = getActivity();
callCategoryAPI();
return view;
}
callCategory()
это вызов API модернизации в отдельном классе контроллера и возвращает ответ через interface
а затем установить данные.
Так что я подозреваю, что мой API возвращает ответ (как его асинхронный), но представления не доступны, так как пользователь изменяет фрагмент (быстро), поэтому представления являются нулевыми.
Я уже пробовала setuserVisibleHint
также пробовал блокировать клики в течение 1200 мс, а также проверял, создан ли мой фрагмент, как остановить этот сбой? и сделать модернизированный вызов Lifecycle зависимым?
Logcat
в com.example.CurrentFragment$1.onApiSuccess(CurrentFragment.java:82) в com.example.services.current_statement.CurrentStatementController$2.onResponse(CurrentStatementController.java:91) в retrofit2.ExecutorCallAdapavaFackback $ $:70) на android.os.Handler.handleCallback(Handler.java:790) на android.os.Handler.dispatchMessage(Handler.java:99) на android.os.Looper.loop(Looper.java:171) на android.app.ActivityThread.main(ActivityThread.java:6606) в java.lang.reflect.Method.invoke(Method.java) в com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:518) в com.android.internal.os.ZygoteInit.main (ZygoteInit.java:823)
-
Неустранимое исключение: java.lang.NullPointerException: попытка вызвать виртуальный метод "void android.widget.TextView.setText(java.lang.CharSequence)" для ссылки на нулевой объект в com.example.fragment.statements.CurrentFragment$1.onApiSuccess(CurrentFragment.java:82) в com.example.services.current_statement.CurrentStatementController$2.onResponse(CurrentStatementController.java:91) в retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(Exava.FactoryHall) handleCallback (Handler.java:790) на android.os.Handler.dispatchMessage(Handler.java:99) на android.os.Looper.loop(Looper.java:171) на android.app.ActivityThread.main (ActivityThread.java): 6606) в java.lang.reflect.Method.invoke(Method.java) в com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:518) в com.android.internal.os.ZygoteInit. Основной (ZygoteInit.java:823)
2 ответа
Установить в вашем фрагменте
if(activity != null && isAdded) {
// perform your task
}
Проверить во фрагменте
if(activity != null && isAdded){
Perform your operation
}
Установить в вашем фрагменте
if(getActivity() != null && isAdded) {
//do your operation
}
Я могу опоздать, но я надеюсь, что смогу помочь и другому разработчику, потому что я тоже столкнулся с этой проблемой. просто используйте isAdded()
в вашем состоянии в onResponse
обратный вызов внутри if-else
пример: внутри вашего onResponse
Перезвоните:
if (isAdded()){
// success response
} else {
if(isAdded()){
// error response
}
}
Код предназначен для котлина в android:
TextView?.text
Вот? означает не ноль
используйте его, как показано выше
Если вы быстро измените пункт меню панели навигации, текущий фрагмент тоже будет заменен новым. Android может удалить все текущие вычисления, выполняемые в основном потоке. Но если какая-либо тяжелая задача, такая как результат фонового сетевого ответа или отложенная задача обработчика, которая имеет ссылку на фрагмент, может найти null, потому что фрагмент уже отсоединен или заменен новым.
Таким образом, вам просто нужно проверить, что фрагмент вашего желания все еще добавлен в действие или нет, до данных ответа процесса, которые поступили в последнее время.
if(frag.isAdded()){
//lets process your delayed response data
}
Используйте эту библиотеку ниже, чтобы заблокировать активность, пока сетевая операция не будет завершена.
Это то, что я использовал для своего приложения на изображении, которое я показал вам раньше.
Это проблема:
Попытка вызвать виртуальный метод "void android.widget.TextView.setText(java.lang.CharSequence)" для ссылки на пустой объект
Вы хотели бы установить текст в текстовое представление, которое является нулевым. Сначала вы должны проверить, что ваше текстовое представление не равно нулю:
if (textview != null){
textview.setText("mytext");
}