Использование RunOnUIThread вызывает исключение нулевого указателя после переключения на другой фрагмент - PullRequest
0 голосов
/ 18 декабря 2018
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()

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Во-первых, вы должны понимать о потоках в Android.В Android у нас есть поток под названием MainUIThread.Я не уверен, что это основной поток или нет.Тем не менее, он имеет экземпляр класса Looper.

Ваш источник фрагмента в основном работает на MainUIThread по умолчанию.Когда вы создаете подкласс TimerTask, вы создаете новый Runnable для запуска вашего источника в другом потоке, верно?

Ваше сообщение об ошибке java.lang.NullPointerException означает, что возвращаемое значение getActivity() метод null.Хорошее место для начала - JavaDocs.Они охватывают это:

Брошенный, когда приложение пытается использовать нуль в случае, когда объект требуется.К ним относятся:

  • Вызов метода экземпляра нулевого объекта.
  • Доступ к полю нулевого объекта или его изменение.
  • Взятие длины нуля, как если быэто был массив.
  • Доступ или изменение пустых слотов, как если бы это был массив.
  • Бросок нулевого значения, как если бы это было значение Throwable.

Приложения должны выдавать экземпляры этого класса, чтобы указать на другое незаконное использование нулевого объекта.

Решение для вас:

  1. Пусть проверит и убедится, что вы не заканчиваете действие.(Другой случай, когда вы отсоединяете этот фрагмент под названием Activity. Поскольку вы используете ViewPager, я полагаю, что вы проводите два раза влево или вправо. По умолчанию он автоматически отсоединяет ваш фрагмент.) Попробуйте отказаться от него.
  2. Если вам нужно закончить свою деятельность, которая содержит ваш фрагмент или отделить ваш фрагмент.Простой способ проверяется нулем перед вызовом 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);
                        }
                    }
                });
            }
        }
    }
    
0 голосов
/ 18 декабря 2018

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

Я могу предложить два варианта:

  1. назначить вывод getActivity () для локальной переменной, когда TimeTaskвыстрелил, проверьте и используйте, если не ноль.
  2. отменить TimerTask в onDetach ().Это рекомендуемый подход.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...