29

My Application consist of 4 fragment as tabs being loaded inside a parent Fragment using FragmentPagerAdapter.

The problem is when I run the app and press back and re-open the app I receive this error log:

FATAL EXCEPTION: main
java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Handler android.support.v4.app.FragmentHostCallback.getHandler()' on a null object reference
    at android.support.v4.app.FragmentManagerImpl.ensureExecReady(FragmentManager.java:1949)
    at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1965)
    at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:620)
    at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:143)
    at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:513)
    ...

the line of code inside parent Fragment is:

viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);

and ViewPage and Adapter both are not null!!

I have to mention that all my Fragments lifecycle is being managed and the null issue is happening inside the adapter!, and the same Adapter is working fine when I use an Activity as parent instead of Fragment!!!

Mohsen Mirhoseini
  • 8,454
  • 5
  • 34
  • 59

9 Answers9

38

After a lot of research, it looks like it is a support library issue:

Activity with fragment and ViewPager crashesh on configuration change
Android Support Library issue 24.1.0

I also found this answer, but it looks unusual adding a flag to my code:

Attempt to invoke virtual method ‘android.os.Handler android.support.v4.app.FragmentHostCallback.getHandler()’ on a null object

I override the finishUpdate method of my FragmentPagerAdapter like this and problem solved for now!

@Override
public void finishUpdate(ViewGroup container) {
    try{
        super.finishUpdate(container);
    } catch (NullPointerException nullPointerException){
        System.out.println("Catch the NullPointerException in FragmentPagerAdapter.finishUpdate");
    }
}

any better answer? please let me know...

Community
  • 1
  • 1
Mohsen Mirhoseini
  • 8,454
  • 5
  • 34
  • 59
16

I have the same issue on my project. But it is my fault.

WHY

I call onBackPressed in a callback after the activity has invoked onDestroy();

Because the mHost instance in the FragmentManager is set to null after onDestroy() called.

and when call onBackPressed it will use the mHost instance again.

Liu Tom
  • 397
  • 2
  • 9
8
@Override
public void onBackPressed() {
//     super.onBackPressed();
       finish();
}  

Override the onBackPressed in activity..
remove the super call : super.onBackPressed
and call finish.

Alien
  • 15,141
  • 6
  • 37
  • 57
varunjohn1990
  • 471
  • 6
  • 6
4

I know it might be late, but here's my stupid mistake I didn't see straight away:

@Override
public void onStop() {
    super.onDestroy(); //I was calling the wrong super
}
James
  • 3,580
  • 3
  • 25
  • 36
3

I had the same issue and it was caused by the reuse of ViewPager instance by different instances of a fragment. A solution was to null the adapter in onDestroyView() method of the fragment.

@Override public void onDestroyView() {
    mViewPager.setAdapter(null);
    super.onDestroyView();
}

Project demoing the issue and the solution can be found here.

sergej shafarenka
  • 20,071
  • 7
  • 67
  • 86
3

I had the same issue. In my case the problem was that I was re-using without noticing the adapter from the previous time opened.

I looked into the FragmentManager.java class that send the exception and on the very same line that crashes says: "Must be called from main thread of fragment host"

my code was:

PagerAdapter adapter = MPageAdapter.getInstance(getSupportFragmentManager()); 
viewPager.setAdapter(adapter);

because I was using my PageAdapter as a bridge to communicate between fragments I used a singleton pattern. That worked well for me but once I repeated this structure in another activity I got the same exception. And the reason was that I forgot to destroy the singleton of my adapter class at the end of every use.

@Override
protected void onDestroy() {
    MPageAdapter.Destroy();  //I forgot this one, that makes singleton = null;
    super.onDestroy();
}
2

I solved it by adding !isFinishing in onBackPressed() of my Activity.

override fun onBackPressed() {
        if (!isFinishing) {            
            super.onBackPressed()
            // your implementation specific code here..
        }
    }

The issue in my case was through some code flow, my DialogFragment was calling the onBackPressed() of its parent Activity just after calling finish() which causing this crash.

Hope it helps if someone is still looking for answer!

Astha Garg
  • 1,022
  • 7
  • 21
0

I was using the wrong activity reference to fetch

getSupportFragmentManager()

Using the correct activity fixed the crash for me.

Varun Bhatia
  • 4,326
  • 32
  • 46
0

Just comment super.onBackPressed() method and write finish() instead

@Override
public void onBackPressed() {
//     super.onBackPressed();
       finish();
}  

In my case this worked!

Hardik Hirpara
  • 2,594
  • 20
  • 34
  • It may work but it's a nonsense answer because you are overriding the 'onBackPressed' behavior when you can easily call 'finish()' instead of using backpressed method – Hanako Dec 24 '21 at 16:57