按钮的OnClickListener引发了空指针异常

11

我正在为一个人工智能学期项目编写一款Android游戏应用程序。在主类的第38行,也就是从启动屏幕中获取新游戏按钮的setOnClickListener处,我遇到了NullPointerException。

相关部分:Class WW3Activity:

public class WW3Activity extends Activity
{
public boolean DebugMode = false;
private String buildMenuEmplacement = ""; 

//[Initialization] Called when the app is first launched
@Override
public void onCreate(Bundle savedInstanceState)
{           
    super.onCreate(savedInstanceState);
    setContentView(R.layout.startscreen);

    //[Initialization] Makes the button resources available to the class
    final Button newGame = (Button) findViewById(R.id.buttonNewGame);
    final Button loadGame = (Button) findViewById(R.id.buttonLoadGame);
    final Button exitGame = (Button) findViewById(R.id.buttonExit);
    final Button about = (Button) findViewById(R.id.buttonAbout);
    final Button troll = (Button) findViewById(R.id.buttonTroll);
    final Button debug = (Button) findViewById(R.id.buttonDebug);

    //[Action] When user pushes the New Game button
    newGame.setOnClickListener(new View.OnClickListener()
    {
        public void onClick(View v)
        {
            // Perform action on click
            setContentView(R.layout.main);
            buttonInitialize();
        }
    });
    //[Action] When user pushes the Exit Game button
    exitGame.setOnClickListener(new View.OnClickListener()
    {
        public void onClick(View v)
        {
            // Perform action on click
            finish();
        }
    });
    //[Action] When user pushes the Debug Mode button
    exitGame.setOnClickListener(new View.OnClickListener()
    {
        public void onClick(View v)
        {
            // Perform action on click
            DebugMode = true;
        }


      });
    }

    //[Initialization] Gets the emplacements ready to be pushed
   public void buttonInitialize()
   {
        final ImageView pe1 = (ImageView) findViewById(R.id.playerEmplacement1);
        final ImageView pe2 = (ImageView) findViewById(R.id.playerEmplacement2);
        final ImageView pe3 = (ImageView) findViewById(R.id.playerEmplacement3);
        final ImageView pc = (ImageView) findViewById(R.id.playerCity);
        final ImageView ee1 = (ImageView) findViewById(R.id.enemyEmplacement1);
        final ImageView ee2 = (ImageView) findViewById(R.id.enemyEmplacement2);
        final ImageView ee3 = (ImageView) findViewById(R.id.enemyEmplacement3);
        final ImageView ec = (ImageView) findViewById(R.id.enemyCity);

        registerForContextMenu(findViewById(R.id.playerEmplacement1));
        registerForContextMenu(findViewById(R.id.playerEmplacement2));
        registerForContextMenu(findViewById(R.id.playerEmplacement3));
        registerForContextMenu(findViewById(R.id.enemyEmplacement1));
        registerForContextMenu(findViewById(R.id.enemyEmplacement2));
        registerForContextMenu(findViewById(R.id.enemyEmplacement3));

        /*empAction(pe1);
        empAction(pe2);
        empAction(pe3);
        empAction(ee1);
        empAction(ee2);
        empAction(ee3);
        empAction(ec);
        empAction(pc);*/
    }

而且 LogCat:

10-24 13:29:12.297: D/dalvikvm(440): GC_FOR_ALLOC freed 40K, 4% free 6356K/6595K, paused 177ms
10-24 13:29:12.303: I/dalvikvm-heap(440): Grow heap (frag case) to 6.653MB for 409616-byte allocation
10-24 13:29:12.503: D/dalvikvm(440): GC_FOR_ALLOC freed <1K, 5% free 6755K/7047K, paused 128ms
10-24 13:29:12.614: D/dalvikvm(440): GC_FOR_ALLOC freed 400K, 8% free 6762K/7303K, paused 57ms
10-24 13:29:12.663: D/AndroidRuntime(440): Shutting down VM
10-24 13:29:12.663: W/dalvikvm(440): threadid=1: thread exiting with uncaught exception (group=0x40014760)
10-24 13:29:12.683: E/AndroidRuntime(440): FATAL EXCEPTION: main
10-24 13:29:12.683: E/AndroidRuntime(440): java.lang.RuntimeException: Unable to start activity ComponentInfo{edu.mbijou.cosc473.ww3/edu.mbijou.cosc473.ww3.WW3Activity}: java.lang.NullPointerException
10-24 13:29:12.683: E/AndroidRuntime(440):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1815)
10-24 13:29:12.683: E/AndroidRuntime(440):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1831)
10-24 13:29:12.683: E/AndroidRuntime(440):  at android.app.ActivityThread.access$500(ActivityThread.java:122)
10-24 13:29:12.683: E/AndroidRuntime(440):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1024)
10-24 13:29:12.683: E/AndroidRuntime(440):  at android.os.Handler.dispatchMessage(Handler.java:99)
10-24 13:29:12.683: E/AndroidRuntime(440):  at android.os.Looper.loop(Looper.java:132)
10-24 13:29:12.683: E/AndroidRuntime(440):  at android.app.ActivityThread.main(ActivityThread.java:4123)
10-24 13:29:12.683: E/AndroidRuntime(440):  at java.lang.reflect.Method.invokeNative(Native Method)
10-24 13:29:12.683: E/AndroidRuntime(440):  at java.lang.reflect.Method.invoke(Method.java:491)
10-24 13:29:12.683: E/AndroidRuntime(440):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
10-24 13:29:12.683: E/AndroidRuntime(440):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
10-24 13:29:12.683: E/AndroidRuntime(440):  at dalvik.system.NativeStart.main(Native Method)
10-24 13:29:12.683: E/AndroidRuntime(440): Caused by: java.lang.NullPointerException
10-24 13:29:12.683: E/AndroidRuntime(440):  at edu.mbijou.cosc473.ww3.WW3Activity.onCreate(WW3Activity.java:38)
10-24 13:29:12.683: E/AndroidRuntime(440):  at android.app.Activity.performCreate(Activity.java:4397)
10-24 13:29:12.683: E/AndroidRuntime(440):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
10-24 13:29:12.683: E/AndroidRuntime(440):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1779)
10-24 13:29:12.683: E/AndroidRuntime(440):  ... 11 more

开始界面.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" >
    <ImageView
        android:id="@+id/logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="493dp"
        android:layout_marginTop="217dp"
        android:src="@drawable/logo" >
    </ImageView>
    <Button
        android:id="@+id/buttonNewGame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/logo"
        android:layout_marginLeft="200dp"
        android:layout_marginTop="133dp"
        android:clickable="true"
        android:text="@string/bNewGame" >
    </Button>
    <Button
        android:id="@+id/buttonLoadGame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/buttonNewGame"
        android:layout_alignLeft="@+id/buttonTroll"
        android:layout_alignRight="@+id/buttonTroll"
        android:clickable="true"
        android:text="@string/bLoadGame" >
    </Button>    <Button
        android:id="@+id/buttonExit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/buttonLoadGame"
        android:layout_alignBottom="@+id/buttonLoadGame"
        android:layout_alignLeft="@+id/buttonDebug"
        android:layout_alignRight="@+id/buttonDebug"
        android:layout_toRightOf="@+id/buttonLoadGame"
        android:clickable="true"
        android:text="@string/bExit" >
    </Button>
    <Button
        android:id="@+id/buttonAbout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/buttonNewGame"
        android:layout_alignRight="@+id/buttonNewGame"
        android:layout_below="@+id/buttonNewGame"
        android:layout_marginTop="50dp"
        android:text="@string/bAbout" />
    <Button
        android:id="@+id/buttonTroll"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/buttonAbout"
        android:layout_alignBottom="@+id/buttonAbout"
        android:layout_centerHorizontal="true"
        android:text="@string/bTrollface" />
    <Button
        android:id="@+id/buttonDebug"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/buttonTroll"
        android:layout_toRightOf="@+id/buttonTroll"
        android:layout_marginLeft="200dp"
        android:text="@string/bDebug" />
</RelativeLayout>

我最初遇到一个NullPointerException,因为我在将布局视图更改为startscreen之前声明了一组按钮,但我已经修复了这个问题,然后出现了这个问题。从技术上讲,这确实是作业,但我认为它并不需要作业标签,因为这不是一种与实际任务本身有关的作业类型问题。


你能贴出你的 startscreen.xml 文件吗? - Zoleas
请添加您的startscreen.xml布局文件。在我看来,buttonNewGame不在此布局中。这就是为什么findViewById返回null,因此在尝试调用此按钮的方法时会抛出NullPointerException的原因。 - Ben Weiss
4个回答

31
findViewById() 返回 null 的唯一原因是你要寻找的 View 不属于当前 View(即使用 setContentView() 设置的 View)。如果 R.id.buttonNewGameR.layout.startscreen 中,请尝试清理并重建你的项目。

我会尝试清理并重新构建。 - Mike
1
如果我们想要使用其他布局的按钮,该怎么办? - user49557

2
似乎 newGame 为空。您是否有多个名为 startscreen.xml 的布局?造成这种异常的常见原因是在一个版本中创建了 buttonNewGame,但在另一个版本中没有;这将导致代码正确构建但在运行时失败,正如您所描述的那样,当活动布局未指定该按钮时。

谢谢你的回答,我开始变得有些疯狂,因为这个按钮不是其他视图或任何东西的一部分。我的问题是,我正在支持多个屏幕尺寸的过程中,我添加了一个没有在所有布局中的按钮。 - ClassA

0

我经常看到这个错误,我的问题在于Android在不同的布局中不正确地维护相同的ID。确保你的ID不仅在一个布局中是唯一的,而且在整个应用程序中也是唯一的。


你的R.id.playerEmplacement1等变量是在哪里声明的? - Raiv
很好,但是在你的活动中,你使用了startscreen,main.xml中的所有元素在这里都不可用...将你的buttonInitialize函数移动到与main.xml对应的活动中。 - Raiv
点击新游戏会将contentview设置为主视图,这是宣告和使用emplacements和cities的地方。 - Mike
我是指创建不同的活动,而不是调用setContentView(main.xml)。 - Raiv
调用setContentView多次并不容易更改上下文视图一旦创建。 - Raiv

0

在第38行设置断点并启动调试器。您很可能正在尝试引用xml文件R.layout.startscreen之外的按钮,这将导致NullPointerException。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接