Trying to remove fragment from view gives me NullPointerException on mNextAnim
Asked Answered
R

7

46

I've got 3 fragments, one NavigationDrawer, one MapFragment, and one user-defined "MapInfoFragment". I want the "MapInfoFragment" to appear semi-transparent over top of the MapFragment on certain events and disappear on others. I don't really care if I completely remove the fragment and create a new one each time, or I just change the visibility and information displayed. Currently I'm just trying to use FragmentManager's .hide() function, but I've also tried .remove and .detach with similar results.

Error:

03-18 14:28:10.965  24711-24711/com.[packageName].asTest D/AndroidRuntime﹕ Shutting down VM
03-18 14:28:10.965  24711-24711/com.[packageName].asTest E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.[packageName].asTest, PID: 24711
java.lang.NullPointerException: Attempt to write to field 'int android.app.Fragment.mNextAnim' on a null object reference
        at android.app.BackStackRecord.run(BackStackRecord.java:658)
        at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447)
        at android.app.FragmentManagerImpl$1.run(FragmentManager.java:443)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5017)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)

Activity_main.xml:

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.[packageName].asTest.MainActivity">

    <!-- As the main content view, the view below consumes the entire
         space available using match_parent in both dimensions. -->
    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <fragment xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:map="http://schemas.android.com/apk/res-auto"
            android:id="@+id/map"
            android:name="com.google.android.gms.maps.MapFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            map:cameraZoom="8"
            map:mapType="satellite"
            map:uiRotateGestures="false"
            android:layout_gravity="center_horizontal|top"
        />
    </FrameLayout>

    <fragment android:id="@+id/navigation_drawer"
        android:layout_width="@dimen/navigation_drawer_width"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:name="com.[packageName].asTest.NavigationDrawerFragment"
        tools:layout="@layout/simple_list_item_1" />

    <fragment android:id="@+id/map_info"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.[packageName].asTest.MapInfoFragment" />




</android.support.v4.widget.DrawerLayout>

Offending Code:

FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.hide(getFragmentManager().findFragmentById(R.id.map_info));
ft.commit();

Update 1

I changed map_info_layout to map_info and there's no change in the error I'm getting. I'd previously had map_info_layout defined as the id for the root FrameLayout of the MapInfoFragment's layout xml, so I think map_info_layout and map_info were pointing to the same thing.

Update 2: My solution

Turned out that I had MapInfoFragment extending android.support.v4.app.Fragment instead of android.app.Fragment and I was using the android.app.FragmentTransaction instead of android.support.v4.app.FragmentTransaction. Switched everything to android.app. since I'm not interested in older device compatibility. Thanks Fllo.

Update 3: General solution

Stop trying to hide null objects

Raphael answered 18/3, 2014 at 19:57 Comment(1)
Might be I'm wrong, but I don't see a fragment named map_info_layout, in your layout, I only see map_info.Propositus
A
117

I know you've solved this yourself, but I want to explain how this error happens, since it just happened to me.

Basically you're calling hide(), remove(), etc., with a null value.

The error isn't obvious, and the stack trace doesn't originate from your own sources when this happens, so it's not trivial to realise what it is.

Aphelion answered 20/5, 2014 at 22:19 Comment(3)
+ 1 for pointing this out. Attempt to write to field 'int *.mNextAnim' on a null object reference is raised when trying to show() or hide() passing a null fragment. F.Hypermetropia
This should be the correct answer, lost so much time with this issue until I've found that: "Basically you're calling hide(), remove(), etc., with a null value." ThanksInterrupted
I had to use getFragmentManager().findFragmentById(R.id.faultyFragment) instead of getFragmentManager().findFragmentById(mReferenceToFaultyFragment.getId()). I got the reference in onCreateView()Indemnification
M
8

It also happens when you call FragmentManager.popBackstack() without there being a fragment in the backstack.

Mark answered 4/2, 2016 at 13:39 Comment(5)
How did you solve it? I tried getBackStackEntryCount() and it did not work.Tetraspore
I fixed it by not doing a popbackstack if there's no fragment in the backstack.Mark
How exactly did you check for fragments in the backstack? I've tried fragmentManager.findFragmentById(CONTAINER_ID) != null and it did not work as well. Not sure what else to check.Tetraspore
I don't check in the backstack. I just wrote my code so that it doesn't pop the backstack if there's no fragment in the backstack. I think generally it's a bad idea to pop the backstack if you don't know what's in it.Mark
use popBackStackImmediate() insteadUnbelieving
F
4

this is because you add or show or hide a fragment which is null now,try to check if it is null ,before you use it!

Frenchify answered 3/4, 2015 at 11:0 Comment(1)
It happens to me before I can replace any fragment. It happens in FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();Davedaveda
R
2

My problem was that FragmentManager's getFragments() sometimes returns a list where some fragments are null, and I was removing those null fragments.

Rosenwald answered 3/11, 2016 at 4:46 Comment(1)
Seems to be my case, but I took fragments from ChildFragmentManager. Thanks!Asbury
N
0

It happended to me only when from one of the fragments in the navigation drawer I showed a DialogFragment by using

newFragment.show(getFragmentManager(), "dialog");

If instead I used

newFragment.show(getChildFragmentManager(), "dialog");

this did not happened.

NOTE: The crash did not happen to me when showing or closing the dialog, but when changing to another fragment from the navigation drawer.

Nims answered 2/6, 2016 at 9:39 Comment(0)
O
0

Properly call show() and hide()...

    private void showFragment(int fragmentIndex, boolean addToBackStack) {
    FragmentManager fm = getFragmentManager();
    FragmentTransaction transaction = fm.beginTransaction();
    for (int i = 0; i < fragments.length; i++) {
        if (i == fragmentIndex) {
            transaction.show(fragments[i]);
        } else {
            transaction.hide(fragments[i]);
        }
    }
    if (addToBackStack) {
        transaction.addToBackStack(null);
    }
    transaction.commit();
}
Orthodox answered 7/11, 2016 at 14:22 Comment(0)
J
0

If you need to use getSupportFragmentManager(), in addition to doing a null check, you must also check to see if that fragment is currently added. If you only use a null, it will still crash. This will work:

if (fragment != null && fragment.isAdded()) {
                    getSupportFragmentManager().beginTransaction().
                            remove(getSupportFragmentManager().findFragmentById(R.id.fragment_container)).commit();
                }
Jazzman answered 29/3, 2021 at 11:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.