I have just written my first android app, and afte

2019-09-03 02:30发布

问题:

I have just started writing my first piece of code in an android app, however when I run it with the following section uncommented it crashes (anything else I tell you would be a useless guess):

  public void onButton1Click(View v){
    if(v.getId() == R.id.button1){

        StringBuilder str = new StringBuilder("");
        if (pepBox.isChecked()) {
            str.append("Pepperoni"+" ");
        }
        if (cheeseBox.isChecked()) {
            str.append("Extra Cheese");
        }
        if (str.length() == 0) {
            str.append("Plain");
        }
        textView.setText(str);
    }
}

With the following error log:

04-07 17:45:30.897: E/AndroidRuntime(15210): FATAL EXCEPTION: main
04-07 17:45:30.897: E/AndroidRuntime(15210): Process: com.ollieapps.helloworld, PID: 15210
04-07 17:45:30.897: E/AndroidRuntime(15210): java.lang.IllegalStateException: Could not execute method of the activity
04-07 17:45:30.897: E/AndroidRuntime(15210):    at android.view.View$1.onClick(View.java:3823)
04-07 17:45:30.897: E/AndroidRuntime(15210):    at android.view.View.performClick(View.java:4438)
04-07 17:45:30.897: E/AndroidRuntime(15210):    at android.view.View$PerformClick.run(View.java:18422)
04-07 17:45:30.897: E/AndroidRuntime(15210):    at android.os.Handler.handleCallback(Handler.java:733)
04-07 17:45:30.897: E/AndroidRuntime(15210):    at android.os.Handler.dispatchMessage(Handler.java:95)
04-07 17:45:30.897: E/AndroidRuntime(15210):    at android.os.Looper.loop(Looper.java:136)
04-07 17:45:30.897: E/AndroidRuntime(15210):    at android.app.ActivityThread.main(ActivityThread.java:5017)
04-07 17:45:30.897: E/AndroidRuntime(15210):    at java.lang.reflect.Method.invoke(Native Method)
04-07 17:45:30.897: E/AndroidRuntime(15210):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
04-07 17:45:30.897: E/AndroidRuntime(15210):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
04-07 17:45:30.897: E/AndroidRuntime(15210): Caused by: java.lang.reflect.InvocationTargetException
04-07 17:45:30.897: E/AndroidRuntime(15210):    at java.lang.reflect.Method.invoke(Native Method)
04-07 17:45:30.897: E/AndroidRuntime(15210):    at android.view.View$1.onClick(View.java:3818)
04-07 17:45:30.897: E/AndroidRuntime(15210):    ... 9 more
04-07 17:45:30.897: E/AndroidRuntime(15210): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.widget.CheckBox.isChecked()' on a null object reference
04-07 17:45:30.897: E/AndroidRuntime(15210):    at com.ollieapps.helloworld.MainActivity.onButton1Click(MainActivity.java:59)
04-07 17:45:30.897: E/AndroidRuntime(15210):    ... 11 more

I'm sorry if I have included to much or too little, this is my first question, also I have already searched for 3 hours.


Full Code: package com.ollieapps.helloworld;

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.CheckBox;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity {
TextView textView; CheckBox pepBox, cheeseBox;

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

    pepBox = (CheckBox) findViewById(R.id.checkBox1);
    cheeseBox = (CheckBox) findViewById(R.id.checkBox2);
    textView = (TextView) findViewById(R.id.textView1);


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


@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, 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);
}

public void onButton1Click(View v){
    if(v.getId() == R.id.button1){

        StringBuilder str = new StringBuilder("");
        if (pepBox.isChecked()) {
            str.append("Pepperoni"+" ");
        }
        if (cheeseBox.isChecked()) {
            str.append("Extra Cheese");
        }
        if (str.length() == 0) {
            str.append("Plain");
        }
        textView.setText(str);
    }
}

/**
 * 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_main, container, false);
        return rootView;
    }
}

}

xml:
fragment:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.ollieapps.helloworld.MainActivity$PlaceholderFragment" >

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:orientation="vertical" >

    <CheckBox
        android:id="@+id/checkBox1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Pepperoni" />

    <CheckBox
        android:id="@+id/checkBox2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ExtraCheese" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onButton1Click"
        android:text="Show" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Plain" />

</LinearLayout>

</RelativeLayout>

Main:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.ollieapps.helloworld.MainActivity"
tools:ignore="MergeRootFrame" />

回答1:

It seems you built your views inside fragment_main.xml and not activity_main.xml.

When you first create a new android project, you have these files which are automatically created and opened:

Then, when you begin, you add views (e.g: a TextView) inside fragment_main.xml file. Finally, you tried to do a basically event with this view inside your Activity, something like this:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main); // Using layout activity_main.xml

        // You try to set a simple text on the view (TextView) previously added
        TextView text = (TextView) findViewById(R.id.textView1);
        text.setText("Simple Text");  // And you get an error here!

        /*
         * You do an fragment transaction to add PlaceholderFragment Fragment
         * on screen - this below snippnet is automatically created.
        */
        if(savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment()).commit();
        }
    } 

You cannot run your app or sometimes you have only a white screen, because the views that you tried to call/display are into the wrong layout..

Solution: Move all your stuff inside onCreateView method into the Fragment class.

As DoctororDrive said in his comment
Call views and do something in the related fragment and not the parent activity.


For example, in your case, these following lines:

pepBox = (CheckBox) findViewById(R.id.checkBox1);
cheeseBox = (CheckBox) findViewById(R.id.checkBox2);
textView = (TextView) findViewById(R.id.textView1);  

might be inside your fragment because you created it in fragment_main.xml layout. Then:

// start fragment
public static class PlaceholderFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

        // Use the layout which is displayed it's fragment_main.xml
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);

        // Find your views here!
        // Don't forget to findViewById attached to the inflated view "rootView.findView..."
        pepBox = (CheckBox) rootView.findViewById(R.id.checkBox1);
        cheeseBox = (CheckBox) rootView.findViewById(R.id.checkBox2);
        textView = (TextView) rootView.findViewById(R.id.textView1);

        /*
         * Do something here: click listener, set a text, check a box..
        */

        return rootView;
    }  

    /*
     * Perform other methods still inside the fragment
    */ 
    public void onButton1Click(View v){
        if(v.getId() == R.id.button1){

            StringBuilder str = new StringBuilder("");
            if (pepBox.isChecked()) {
                str.append("Pepperoni"+" ");
            }
            if (cheeseBox.isChecked()) {
                str.append("Extra Cheese");
            }
            if (str.length() == 0) {
                str.append("Plain");
            }
            textView.setText(str);
        }
    }
}
// end fragment


回答2:

 if (pepBox.isChecked()) {

This line of code is failing with a NullPointerException because pepBox was declared but it's not being initialized as it should (and is therefore null at this point in the code).

Here is its declaration line:

TextView textView; CheckBox pepBox, cheeseBox;

And here is its initialization:

pepBox = (CheckBox) findViewById(R.id.checkBox1);

The problem is that (a) this line is not be called, or (b) findViewById(R.id.checkBox1) is returning null.

If findViewByID is returning null then you probably want to refer to this question, which addresses exactly this issue. Its "related questions", down the right-hand side, should also be helpful.