切换到另一个片段后使用 RunOnUIThread 导致空指针异常

Vis*_*rma 1 android nullpointerexception android-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);
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在使用此代码更改视图中的图像。但问题是我在片段中使用它,当我更改片段和应用程序运行几秒钟,然后突然弹出的空指针错误。现在我理解的原因是它试图更改图像但没有找到视图并创建此错误我不知道该怎么做。请帮忙 :)

错误

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()
Run Code Online (Sandbox Code Playgroud)

Trầ*_*Tâm 5

首先,您应该了解 Android 中的线程。在 Android 中,我们有一个名为 MainUIThread 的线程。我不确定这是否是主线程。但是,它有一个Looper类的实例。

默认情况下,您的片段源基本上在 MainUIThread 上运行。当您创建 的子类时TimerTask,您正在创建一个新的 Runnable 以在另一个线程中运行您的源代码,对吗?

您的错误消息java.lang.NullPointerException意味着方法的返回值getActivity()null。JavaDocs 是一个很好的起点。他们涵盖了以下内容:

当应用程序在需要对象的情况下尝试使用 null 时抛出。这些包括:

  • 调用空对象的实例方法。
  • 访问或修改空对象的字段。
  • 将 null 的长度当作一个数组。
  • 访问或修改 null 的插槽,就好像它是一个数组一样。
  • 将 null 视为 Throwable 值。

应用程序应抛出此类的实例以指示 null 对象的其他非法使用。

为您提供的解决方案:

  1. 让我们检查并确保您没有完成活动。(另一种情况是你分离了这个叫Activity的Fragment。因为你使用的是ViewPager,我猜你是向左或向右滑动两次。默认情况下它会自动分离你的Fragment)尝试放弃它。
  2. 如果您必须完成包含您的 Fragment 的 Activity 或必须分离您的 Fragment。最简单的方法是在调用runOnUiThread()方法之前检查 null 。

    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);
                        }
                    }
                });
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)