Использование RunOnUIThread вызывает исключение нулевого указателя после переключения на другой фрагмент
public class ViewPagerTask extends TimerTask {
@Override
public void run() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (viewPager.getCurrentItem() == 0){
viewPager.setCurrentItem(1);
} else if (viewPager.getCurrentItem() == 1){
viewPager.setCurrentItem(2);
} else viewPager.setCurrentItem(0);
}
});
}
}
Я использую этот код для изменения изображений в представлении. Но проблема в том, что я использую его во фрагменте, и когда я изменяю фрагмент, приложение запускается в течение нескольких секунд, а затем внезапно появляется ошибка нулевого указателя. Теперь, что я понимаю, причина в том, что он пытается изменить изображение, но не находит представление и создает эту ошибку, я понятия не имею, что делать. Пожалуйста помоги:)
ошибка
E/AndroidRuntime: FATAL EXCEPTION: Timer-0
Process: com.example.android.indianmetro, PID: 5150
java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.support.v4.app.FragmentActivity.runOnUiThread(java.lang.Runnable)'
on a null object reference
at com.example.android.indianmetro.HomeFragment$ViewPagerTask.run(HomeFragment.java:258)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
E/AbstractTracker: Can't create handler inside thread that has not called
Looper.prepare()
3 ответа
Первое, вы должны понимать о потоках в Android. В Android у нас есть поток под названием MainUIThread. Я не уверен, что это основной поток или нет. Тем не менее, он имеет экземпляр Looper
учебный класс.
Ваш исходный фрагмент по умолчанию работает на MainUIThread. Когда вы создаете подкласс TimerTask
, вы создаете новый Runnable для запуска вашего источника в другом потоке, верно?
Ваше сообщение об ошибке java.lang.NullPointerException
означает, что возвращаемое значение getActivity()
метод null
, Хорошее место для начала - JavaDocs. У них есть это покрыто:
Брошенный, когда приложение пытается использовать нуль в случае, когда объект требуется. Они включают:
- Вызов метода экземпляра нулевого объекта.
- Доступ или изменение поля нулевого объекта.
- Принимая длину нуля, как если бы это был массив.
- Доступ или изменение пустых слотов, как если бы это был массив.
- Бросить ноль, как если бы это было значение Throwable.
Приложения должны генерировать экземпляры этого класса, чтобы указать на другое незаконное использование нулевого объекта.
Решение для вас:
- Позвольте проверить и убедитесь, что вы не заканчиваете деятельность. (Другой случай, когда вы отсоединяете этот фрагмент под названием Activity. Поскольку вы используете ViewPager, я полагаю, что вы проводите два раза влево или вправо. По умолчанию он автоматически отсоединяет ваш фрагмент.) Попробуйте отказаться от него.
Если вам нужно закончить свою активность, которая содержит ваш фрагмент или отсоединить ваш фрагмент. Простой способ проверяется нулевым перед вызовом
runOnUiThread()
метод.public class ViewPagerTask extends TimerTask { @Override public void run() { Activity activity = getActivity(); if (activity != null) { activity.runOnUiThread(new Runnable() { @Override public void run() { if (viewPager.getCurrentItem() == 0) { viewPager.setCurrentItem(1); } else if (viewPager.getCurrentItem() == 1) { viewPager.setCurrentItem(2); } else { viewPager.setCurrentItem(0); } } }); } } }
Ваш TimerTask
срабатывает после удаления фрагмента. В таком случае, getActivity()
вернет ноль и, следовательно, исключение.
Я могу предложить два варианта:
- назначить вывод getActivity() для локальной переменной, когда
TimeTask
уволен, проверьте и используйте, если не ноль. - отменить свой
TimerTask
в onDetach(). Это рекомендуемый подход.
public class The_slide_timer extends TimerTask {
@Override
public void run() {
Activity activity = getActivity();
if (activity != null) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (page.getCurrentItem() < listItems.size() - 1) {
page.setCurrentItem(page.getCurrentItem() + 1);
} else
page.setCurrentItem(0);
}
});
}
}
}
просто проверяю, является ли активность нулевой или нет, просто решаю проблемы.