Starting Activity from Fragment causes NullPointerException

AndroidAndroid ActivityAndroid FragmentsAndroid Viewpager

Android Problem Overview


I'm stuck here with a problem starting an activity from a Button inside a Fragment. Here is my code:

ViewPagerAdapter.java

import java.util.List;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class ViewPagerAdapter extends FragmentPagerAdapter {
	
	private List<Fragment> fragments;
	
	public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
		super(fm);
		this.fragments = fragments;
	}
	
	@Override
	public int getCount() {
		return this.fragments.size();
	}

	@Override
	public Fragment getItem(int position) {
		return this.fragments.get(position);
	}

}

ViewPagerActivity.java

import java.util.List;
import java.util.Vector;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.util.Log;
import com.package.here.Class1Overview;
import com.package.here.Class1Overview;
import com.package.here.Class1Overview;

public class ViewPagerActivity extends FragmentActivity{
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.viewpager);
		
		ViewPager pager = (ViewPager)super.findViewById(R.id.my_viewpager);
		pager.setAdapter(initialisePaging());
	}
	
	private ViewPagerAdapter initialisePaging() {
		
		List<Fragment> fragments = new Vector<Fragment>();
		fragments.add(Fragment.instantiate(this, Class1Overview.class.getName()));
		fragments.add(Fragment.instantiate(this, Class2Overview.class.getName()));
		fragments.add(Fragment.instantiate(this, Class3Overview.class.getName()));
		return new ViewPagerAdapter(super.getSupportFragmentManager(), fragments);			
	}

}

Class1Overview.java (Here is the button)

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import com.package.here.R;

public class FuelOverview extends Fragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		if (container == null) {
            return null;
        }
		View v = (LinearLayout)inflater.inflate(R.layout.class_one_layout, container, false);
		View AddBtn = v.findViewById(R.id.btn_add);
		((Button) AddBtn).setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent intent = new Intent();
				intent.setClass(getActivity(), ActivityToStart.class);
				startActivity(intent);
			}
		});
		
		return v;
	}
}

And this is my LogCat:

01-05 19:39:00.913: E/AndroidRuntime(10557): Uncaught handler: thread main exiting due to uncaught exception
01-05 19:39:01.034: E/AndroidRuntime(10557): java.lang.RuntimeException: Unable to pause activity {com.package.here/com.package.here.ViewPagerActivity}: java.lang.NullPointerException
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3162)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3119)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3102)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at android.app.ActivityThread.access$2400(ActivityThread.java:119)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1870)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at android.os.Handler.dispatchMessage(Handler.java:99)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at android.os.Looper.loop(Looper.java:123)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at android.app.ActivityThread.main(ActivityThread.java:4363)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at java.lang.reflect.Method.invokeNative(Native Method)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at java.lang.reflect.Method.invoke(Method.java:521)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at dalvik.system.NativeStart.main(Native Method)
01-05 19:39:01.034: E/AndroidRuntime(10557): Caused by: java.lang.NullPointerException
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at android.support.v4.app.FragmentManagerImpl.saveFragmentBasicState(FragmentManager.java:1576)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1617)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at android.support.v4.app.FragmentActivity.onSaveInstanceState(FragmentActivity.java:481)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at android.app.Activity.performSaveInstanceState(Activity.java:1022)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1180)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3144)
01-05 19:39:01.034: E/AndroidRuntime(10557): 	... 12 more
01-05 19:39:01.423: I/dalvikvm(10557): threadid=7: reacting to signal 3

ViewPager itself is working fine. It seems to be an error pausing the FragmentActivity, but i can't figure it out. The only thing I found was this post on google http://code.google.com/p/android/issues/detail?id=19917

I also got through the google example code to make sure I mainly use the same technique...

Edit: to make sure the ClickListener works, I tried a Toast in the onClick method - works perfectly.

Android Solutions


Solution 1 - Android

Quick fix is

class MyFragment extends Fragment {

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        setUserVisibleHint(true);
    }

And wait for update in safe mode :)

Solution 2 - Android

This is a known problem and I'm shocked to find that no one has filed a bug on the public bug tracker for this.

Your problem stems from this:

if (f.mSavedViewState != null) {
    if (result == null) {
        result = new Bundle();
    }
    result.putSparseParcelableArray(
            FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState);
}
if (!f.mUserVisibleHint) {
    // Only add this if it's not the default value
    result.putBoolean(FragmentManagerImpl.USER_VISIBLE_HINT_TAG, f.mUserVisibleHint);
}

You should notice that if result is null coming into this code and the first if is not triggered you'll get a NullPointerException if we enter the second if.

It should read:

if (f.mSavedViewState != null) {
    if (result == null) {
        result = new Bundle();
    }
    result.putSparseParcelableArray(
            FragmentManagerImpl.VIEW_STATE_TAG, f.mSavedViewState);
}
if (!f.mUserVisibleHint) {
    if (result == null) {
        result = new Bundle();
    }
    // Only add this if it's not the default value
    result.putBoolean(FragmentManagerImpl.USER_VISIBLE_HINT_TAG, f.mUserVisibleHint);
}

I submitted a patch for this a week or two ago: https://android-review.googlesource.com/31261

Solution 3 - Android

According to a post here, you should be using FragmentStatePagerAdapter rather than FragmentPagerAdapter. I had the same problem you described, and making that switch worked for me.

Solution 4 - Android

I just had the same problem - the issue for me was caused when I added a new fragment to my project with an empty layout. It seems that if nothing is saved to the bundle during Fragment.onSaveInstanceState(Bundle outState) it causes a null pointer exception in FragmentManagerImpl.saveFragmentBasicState.

Adding some views to my layouts fixed the issue (after hours spent bashing my head against a wall). Using android support library v4 revision 10.

Also when using a ListView as the root for the fragment layout, if the listview has no elements you will also get the crash. In the fragment class, override onSaveInstanceState like this to put some data in the bundle:

@Override
public void onSaveInstanceState(Bundle outState)
{
    super.onSaveInstanceState(outState);
    outState.putString("DO NOT CRASH", "OK");
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJukeView Question on Stackoverflow
Solution 1 - AndroidVadimView Answer on Stackoverflow
Solution 2 - AndroidJake WhartonView Answer on Stackoverflow
Solution 3 - AndroidHarlo HolmesView Answer on Stackoverflow
Solution 4 - AndroidWayne UrodaView Answer on Stackoverflow