Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NullPointerException accessing views in onCreate()

People also ask

What does onCreate method do?

onCreate(Bundle savedInstanceState) Function in Android: When an Activity first call or launched then onCreate(Bundle savedInstanceState) method is responsible to create the activity.

Why do we override onCreate?

onCreate is "Overridden" because Activity has an existing implementation that your class MainActivity is replacing with it's own implementation. you would say "implemented" if the method is only declared in an interface, but there is no implementation in a super class your are replacing.

What does onCreate mean?

onCreate is used to start an activity. super is used to call the parent class constructor. setContentView is used to set the xml.

What is the argument for onCreate function used for?

onCreate(Bundle) is called when the activity first starts up. You can use it to perform one-time initialization such as creating the user interface. onCreate() takes one parameter that is either null or some state information previously saved by the onSaveInstanceState .


The tutorial is probably outdated, attempting to create an activity-based UI instead of the fragment-based UI preferred by wizard-generated code.

The view is in the fragment layout (fragment_main.xml) and not in the activity layout (activity_main.xml). onCreate() is too early in the lifecycle to find it in the activity view hierarchy, and a null is returned. Invoking a method on null causes the NPE.

The preferred solution is to move the code to the fragment onCreateView(), calling findViewById() on the inflated fragment layout rootView:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
  View rootView = inflater.inflate(R.layout.fragment_main, container,
      false);

  View something = rootView.findViewById(R.id.something); // not activity findViewById()
  something.setOnClickListener(new View.OnClickListener() { ... });

  return rootView;
}

As a side note, the fragment layout will eventually be a part of the activity view hierarchy and discoverable with activity findViewById() but only after the fragment transaction has been run. Pending fragment transactions get executed in super.onStart() after onCreate().


Try OnStart() method and just use

View view = getView().findViewById(R.id.something);

or Declare any View using getView().findViewById method in onStart()

Declare click listener on view by anyView.setOnClickListener(this);


Try to shift your accessing views to the onViewCreated method of fragment because sometimes when you try to access the views in onCreate method they are not rendered at the time resulting null pointer exception.

 @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
     View something = findViewById(R.id.something);
     something.setOnClickListener(new View.OnClickListener() { ... }); // NPE HERE

     if (savedInstanceState == null) {
           getSupportFragmentManager().beginTransaction()
            .add(R.id.container, new PlaceholderFragment()).commit();
    }
 }

Agreed, this is a typical error because people often don't really understand how Fragments work when they begin working on Android development. To alleviate confusion, I created a simple example code that I originally posted on Application is stopped in android emulator , but I posted it here as well.

An example is the following:

public class ContainerActivity extends FragmentActivity implements ExampleFragment.Callback
{
    @Override
    public void onCreate(Bundle saveInstanceState)
    {
        super.onCreate(saveInstanceState);
        this.setContentView(R.layout.activity_container);
        if (saveInstanceState == null)
        {               
             getSupportFragmentManager().beginTransaction()
                .add(R.id.activity_container_container, new ExampleFragment())
                .addToBackStack(null)
             .commit();
        }
        getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener()
        {
            public void onBackStackChanged()
            {
                int backCount = getSupportFragmentManager().getBackStackEntryCount();
                if (backCount == 0)
                {
                    finish();
                }
            }
        });
    }

    @Override
    public void exampleFragmentCallback()
    {
        Toast.makeText(this, "Hello!", Toast.LENGTH_LONG).show();
    }
}

activity_container.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/activity_container_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

ExampleFragment:

public class ExampleFragment extends Fragment implements View.OnClickListener
{
    public static interface Callback
    {
        void exampleFragmentCallback();
    }

    private Button btnOne;
    private Button btnTwo;
    private Button btnThree;

    private Callback callback;

    @Override
    public void onAttach(Activity activity)
    {
        super.onAttach(activity);
        try
        {
            this.callback = (Callback) activity;
        }
        catch (ClassCastException e)
        {
            Log.e(this.getClass().getSimpleName(), "Activity must implement Callback interface.", e);
            throw e;
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View rootView = inflater.inflate(R.layout.fragment_example, container, false);

        btnOne = (Button) rootView.findViewById(R.id.example_button_one);
        btnTwo = (Button) rootView.findViewById(R.id.example_button_two);
        btnThree = (Button) rootView.findViewById(R.id.example_button_three);

        btnOne.setOnClickListener(this);
        btnTwo.setOnClickListener(this);
        btnThree.setOnClickListener(this);
        return rootView;
    }

    @Override
    public void onClick(View v)
    {
        if (btnOne == v)
        {
            Toast.makeText(getActivity(), "One.", Toast.LENGTH_LONG).show();
        }
        else if (btnTwo == v)
        {
            Toast.makeText(getActivity(), "Two.", Toast.LENGTH_LONG).show();
        }
        else if (btnThree == v)
        {
            callback.exampleFragmentCallback();
        }
    }
}

fragment_example.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <Button
            android:id="@+id/example_button_one"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="30dp"
            android:text="@string/hello" 
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"/>

        <Button
            android:id="@+id/example_button_two"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/example_button_one"
            android:layout_alignRight="@+id/example_button_one"
            android:layout_below="@+id/example_button_one"
            android:layout_marginTop="30dp"
            android:text="@string/hello" />

        <Button
            android:id="@+id/example_button_three"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/example_button_two"
            android:layout_alignRight="@+id/example_button_two"
            android:layout_below="@+id/example_button_two"
            android:layout_marginTop="30dp"
            android:text="@string/hello" />

</RelativeLayout>

And that should be a valid example, it shows how you can use an Activity to display a Fragment, and handle events in that Fragment. And also how to communicate with the containing Activity.


The view "something" is in fragment and not in activity, so instead of accessing it in activity you must access it in the fragment class like

In PlaceholderFragment.class

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_main, container,
  false);

View something = root .findViewById(R.id.something);
something.setOnClickListener(new View.OnClickListener() { ... });

return root;
}