Question

I just started learning Android programming and have run into trouble. I'm using the book "Android Programming The Big Nerd Ranch Guide". My IDE is Eclipse and Genymotion to emulate the app. Here's the logcat:

04-13 00:19:48.065: D/dalvikvm(1256): Late-enabling CheckJNI
04-13 00:19:48.781: D/AndroidRuntime(1256): Shutting down VM
04-13 00:19:48.785: W/dalvikvm(1256): threadid=1: thread exiting with uncaught exception (group=0xa4d8ab20)
04-13 00:19:48.785: E/AndroidRuntime(1256): FATAL EXCEPTION: main
04-13 00:19:48.785: E/AndroidRuntime(1256): Process: com.bignerdranch.android.geoquiz, PID: 1256
04-13 00:19:48.785: E/AndroidRuntime(1256): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.bignerdranch.android.geoquiz/com.bignerdranch.android.geoquiz.QuizActivity}: java.lang.NullPointerException
04-13 00:19:48.785: E/AndroidRuntime(1256):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
04-13 00:19:48.785: E/AndroidRuntime(1256):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
04-13 00:19:48.785: E/AndroidRuntime(1256):     at android.app.ActivityThread.access$800(ActivityThread.java:135)
04-13 00:19:48.785: E/AndroidRuntime(1256):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
04-13 00:19:48.785: E/AndroidRuntime(1256):     at android.os.Handler.dispatchMessage(Handler.java:102)
04-13 00:19:48.785: E/AndroidRuntime(1256):     at android.os.Looper.loop(Looper.java:136)
04-13 00:19:48.785: E/AndroidRuntime(1256):     at android.app.ActivityThread.main(ActivityThread.java:5017)
04-13 00:19:48.785: E/AndroidRuntime(1256):     at java.lang.reflect.Method.invokeNative(Native Method)
04-13 00:19:48.785: E/AndroidRuntime(1256):     at java.lang.reflect.Method.invoke(Method.java:515)
04-13 00:19:48.785: E/AndroidRuntime(1256):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
04-13 00:19:48.785: E/AndroidRuntime(1256):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
04-13 00:19:48.785: E/AndroidRuntime(1256):     at dalvik.system.NativeStart.main(Native Method)
04-13 00:19:48.785: E/AndroidRuntime(1256): Caused by: java.lang.NullPointerException
04-13 00:19:48.785: E/AndroidRuntime(1256):     at com.bignerdranch.android.geoquiz.QuizActivity.onCreate(QuizActivity.java:30)
04-13 00:19:48.785: E/AndroidRuntime(1256):     at android.app.Activity.performCreate(Activity.java:5231)
04-13 00:19:48.785: E/AndroidRuntime(1256):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
04-13 00:19:48.785: E/AndroidRuntime(1256):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
04-13 00:19:48.785: E/AndroidRuntime(1256):     ... 11 more
04-13 00:19:56.345: I/Process(1256): Sending signal. PID: 1256 SIG: 9

Here's the fragment_quiz.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="24dp"
        android:text="@string/question_text" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/true_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/true_button" />

        <Button
            android:id="@+id/false_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/false_button" />

    </LinearLayout>

</LinearLayout>

The QuizActivity.java file (most of the code imported by Eclipse):

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

public class QuizActivity extends ActionBarActivity {

    private Button mTrueButton;
    private Button mFalseButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_quiz);

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

        mTrueButton = (Button) findViewById(R.id.true_button);
        mTrueButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(QuizActivity.this, R.string.incorrect_toast, Toast.LENGTH_SHORT)
                        .show();

            }
        });

        mFalseButton = (Button) findViewById(R.id.false_button);
        mFalseButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Toast.makeText(QuizActivity.this, R.string.correct_toast, Toast.LENGTH_SHORT)
                        .show();

            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.quiz, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

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

}

What am I doing wrong?

Was it helpful?

Solution

Put your layout definitions in the PlaceholderFragment class. For the findViewById, use rootView.findViewById. For the context, use getActivity().

Why does this work? There are actually 2 independent layouts shown as one in your screen. The master one shows everything, including a fragment. A Fragment is basically a self-contained mini activity, very useful in Tablet development, and mildly useful even just for a phone type device. Your layouts are in the fragment_quiz xml file, which is only inflated inside the fragment, in the onCreateView statement. So long as you use the findViewById after it's been inflated, you'll be fine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top