androidnullpointerexceptionandroid-runonuithread

Using RunOnUIThread causing null pointer Exception After Switching to another Fragment


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);
            }
        });
    }
}

I'm using this code to change images in a view. But the problem is I'm using it in fragment and when I change the fragment and app runs for few seconds and then suddenly pop's null pointer error. Now What I understand the reason is that it tries to change the image but doesn't find the view and create this error I have no clue what to do. Please Help :)

Error

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()

Solution

  • The first, you should understand about threads in Android. In Android, we have a thread called MainUIThread. I'm not sure that's the main thread or not. However, It has an instance of Looper class.

    Your fragment source basically runs on MainUIThread by default. When you create the sub-class of TimerTask, you are creating a new Runnable for run your source in another thread, is that right?

    Your error message java.lang.NullPointerException means that the return value of getActivity() method are null. A good place to start is the JavaDocs. They have this covered:

    Thrown when an application attempts to use null in a case where an object is required. These include:

    Applications should throw instances of this class to indicate other illegal uses of the null object.

    The solution for you:

    1. Let check and make sure you are not finishing the Activity. (Another case that's you detach this Fragment of called Activity. Because you are using ViewPager, I guess that you are swipe two times to left or right. It automatically detach your fragment by default) Try to abandon it.
    2. If you have to finish your Activity which contains your Fragment or has to detach your fragment. The easy way is checked null before call runOnUiThread() method.

      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);
                          }
                      }
                  });
              }
          }
      }