Android NullPointerException 导致崩溃
Posted
技术标签:
【中文标题】Android NullPointerException 导致崩溃【英文标题】:Android NullPointerException causing crash 【发布时间】:2012-05-03 22:14:13 【问题描述】:我正在创建一个安卓纸牌游戏。我创建了一个扑克牌类和一个纸牌类。当我运行示例代码时,它无法构建甲板。这是我的代码以及 logcat
PlayingCard.java
package com.michaelpeerman.hi_low;
public class PlayingCard
public String[] CardSuit = "SPADE","HEART","CLUB","DIAMOND";
public String[] CardRank= "ACE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE","JACK","QUEEN","KING";
public String theSuit;
public int theRank;
public boolean theState;
public PlayingCard()
theSuit = "SPADE";
theRank = 1;
theState = false;
public PlayingCard(String mySuit, int myRank)
theSuit = mySuit;
theRank = myRank;
public int getRank()
return theRank;
public String getSuit()
return theSuit;
public boolean getState()
return theState;
public void setState(boolean myState)
theState = myState;
public void setRank(int myRank)
theRank = myRank;
public void setSuit(String mySuit)
theSuit = mySuit;
public String getCardString()
String cardString = null;
String theCardRanks[] = "A","2","3","4","5","6","7","8","9","T","J","Q","K";
if (theSuit == "CLUB")
cardString = "C"+theCardRanks[theRank-1];
else if (theSuit == "SPADE")
cardString = "S"+theCardRanks[theRank-1];
else if (theSuit == "HEART")
cardString = "H"+theCardRanks[theRank-1];
else if (theSuit == "DIAMOND")
cardString = "D"+theCardRanks[theRank-1];
return cardString;
CardDeck.java
package com.michaelpeerman.hi_low;
import java.util.Random;
import com.michaelpeerman.hi_low.PlayingCard;
public class CardDeck
public PlayingCard[] cardArray;
public int num_decks;
public int cards_left;
public CardDeck(int my_decks)
num_decks = my_decks;
cardArray = new PlayingCard[52*num_decks];
cards_left = 52*num_decks;
for (int i=0; i< num_decks; i++)
for (int j = 0; j < 13; j++)
cardArray[(j+(52*i))].setSuit("SPADE");
cardArray[j+13+(52*i)].setSuit("HEART");
cardArray[j+26+(52*i)].setSuit("CLUB");
cardArray[j+39+(52*i)].setSuit("DIAMOND");
if (j==0)
cardArray[j+(52*i)].setRank(1);
cardArray[j+13+(52*i)].setRank(1);
cardArray[j+26+(52*i)].setRank(1);
cardArray[j+39+(52*i)].setRank(1);
else if (j==1)
cardArray[j+(52*i)].setRank(2);
cardArray[j+13+(52*i)].setRank(2);
cardArray[j+26+(52*i)].setRank(2);
cardArray[j+39+(52*i)].setRank(2);
else if (j==2)
cardArray[j+(52*i)].setRank(3);
cardArray[j+13+(52*i)].setRank(3);
cardArray[j+26+(52*i)].setRank(3);
cardArray[j+39+(52*i)].setRank(3);
else if (j==3)
cardArray[j+(52*i)].setRank(4);
cardArray[j+13+(52*i)].setRank(4);
cardArray[j+26+(52*i)].setRank(4);
cardArray[j+39+(52*i)].setRank(4);
else if (j==4)
cardArray[j+(52*i)].setRank(5);
cardArray[j+13+(52*i)].setRank(5);
cardArray[j+26+(52*i)].setRank(5);
cardArray[j+39+(52*i)].setRank(5);
else if (j==5)
cardArray[j+(52*i)].setRank(6);
cardArray[j+13+(52*i)].setRank(6);
cardArray[j+26+(52*i)].setRank(6);
cardArray[j+39+(52*i)].setRank(6);
else if (j==6)
cardArray[j+(52*i)].setRank(7);
cardArray[j+13+(52*i)].setRank(7);
cardArray[j+26+(52*i)].setRank(7);
cardArray[j+39+(52*i)].setRank(7);
else if (j==7)
cardArray[j+(52*i)].setRank(8);
cardArray[j+13+(52*i)].setRank(8);
cardArray[j+26+(52*i)].setRank(8);
cardArray[j+39+(52*i)].setRank(8);
else if (j==8)
cardArray[j+(52*i)].setRank(9);
cardArray[j+13+(52*i)].setRank(9);
cardArray[j+26+(52*i)].setRank(9);
cardArray[j+39+(52*i)].setRank(9);
else if (j==9)
cardArray[j+(52*i)].setRank(10);
cardArray[j+13+(52*i)].setRank(10);
cardArray[j+26+(52*i)].setRank(10);
cardArray[j+39+(52*i)].setRank(10);
else if (j==10)
cardArray[j+(52*i)].setRank(11);
cardArray[j+13+(52*i)].setRank(11);
cardArray[j+26+(52*i)].setRank(11);
cardArray[j+39+(52*i)].setRank(11);
else if (j==11)
cardArray[j+(52*i)].setRank(12);
cardArray[j+13+(52*i)].setRank(12);
cardArray[j+26+(52*i)].setRank(12);
cardArray[j+39+(52*i)].setRank(12);
else if (j==12)
cardArray[j+(52*i)].setRank(13);
cardArray[j+13+(52*i)].setRank(13);
cardArray[j+26+(52*i)].setRank(13);
cardArray[j+39+(52*i)].setRank(13);
public void useCard()
cards_left = cards_left - 1;
public int get_cards_left()
return cards_left;
public void setCard(int card, PlayingCard myCard)
cardArray[card]=myCard;
public PlayingCard getCard(int card)
return cardArray[card];
public void printDeck()
for (int j = 0; j < (52*num_decks); j++)
// Print out to textview
//String cardString = cardArray[j].getCardString();
public void suffleDeck()
for (int i = 0; i < 100*num_decks; i++)
int rand1 = 1 + new Random().nextInt(52*num_decks);
int rand2 = 1 + new Random().nextInt(52*num_decks);
PlayingCard tmpCard = cardArray[rand1];
cardArray[rand1] = cardArray[rand2];
cardArray[rand2] = tmpCard;
public boolean isDeckFinished()
boolean isFinished =true;
for (int i = 0; i<52*num_decks; i++)
PlayingCard myCard = cardArray[i];
if (myCard.getState() == false)
isFinished = false;
return isFinished;
StartScreen.java
package com.michaelpeerman.hi_low;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import com.michaelpeerman.hi_low.R;
import com.michaelpeerman.hi_low.CardDeck;
import com.michaelpeerman.hi_low.PlayingCard;
public class StartScreen extends Activity
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
CardDeck myDeck = new CardDeck(1);
int cards = myDeck.cards_left;
String text = Integer.toString(cards);
TextView t=new TextView(this);
t=(TextView)findViewById(R.id.main_text);
t.append(text);
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_
android:layout_ >
<ScrollView
android:layout_
android:layout_>
<TextView
android:id="@+id/main_text"
android:layout_
android:layout_
/>
</ScrollView>
</LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.michaelpeerman.hi_low"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="13" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".StartScreen"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
LogCat 输出
05-03 18:03:55.067: E/AndroidRuntime(9805): FATAL EXCEPTION: main
05-03 18:03:55.067: E/AndroidRuntime(9805): java.lang.RuntimeException: Unable to start activity ComponentInfocom.michaelpeerman.hi_low/com.michaelpeerman.hi_low.StartScreen: java.lang.NullPointerException
05-03 18:03:55.067: E/AndroidRuntime(9805): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
05-03 18:03:55.067: E/AndroidRuntime(9805): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
05-03 18:03:55.067: E/AndroidRuntime(9805): at android.app.ActivityThread.access$600(ActivityThread.java:123)
05-03 18:03:55.067: E/AndroidRuntime(9805): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
05-03 18:03:55.067: E/AndroidRuntime(9805): at android.os.Handler.dispatchMessage(Handler.java:99)
05-03 18:03:55.067: E/AndroidRuntime(9805): at android.os.Looper.loop(Looper.java:137)
05-03 18:03:55.067: E/AndroidRuntime(9805): at android.app.ActivityThread.main(ActivityThread.java:4424)
05-03 18:03:55.067: E/AndroidRuntime(9805): at java.lang.reflect.Method.invokeNative(Native Method)
05-03 18:03:55.067: E/AndroidRuntime(9805): at java.lang.reflect.Method.invoke(Method.java:511)
05-03 18:03:55.067: E/AndroidRuntime(9805): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-03 18:03:55.067: E/AndroidRuntime(9805): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-03 18:03:55.067: E/AndroidRuntime(9805): at dalvik.system.NativeStart.main(Native Method)
05-03 18:03:55.067: E/AndroidRuntime(9805): Caused by: java.lang.NullPointerException
05-03 18:03:55.067: E/AndroidRuntime(9805): at com.michaelpeerman.hi_low.CardDeck.<init>(CardDeck.java:18)
05-03 18:03:55.067: E/AndroidRuntime(9805): at com.michaelpeerman.hi_low.StartScreen.onCreate(StartScreen.java:16)
05-03 18:03:55.067: E/AndroidRuntime(9805): at android.app.Activity.performCreate(Activity.java:4465)
05-03 18:03:55.067: E/AndroidRuntime(9805): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
05-03 18:03:55.067: E/AndroidRuntime(9805): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
05-03 18:03:55.067: E/AndroidRuntime(9805): ... 11 more
【问题讨论】:
【参考方案1】:您正在正确地创建cardArray
,但您没有使用对PlayingCard
的任何引用来填充它。在您将它们设置为某个值之前,它们都是空值。
【讨论】:
我想用 cardArray = new PlayingCard[52*num_decks];在 CardDeck 类的构造函数中是这样做的吗? 所以我需要运行 cardArray[j] = new PlayingCard;对吗? 没有。它只是为52*num_decks
的引用量创建和分配内存。在您明确创建对象之前,不会创建对象。 for(int k = 0; k < cardArray.length; i++)cardArray[k] = new PlayingCard();
会这样做。
嗯,看来我的回答为时已晚 :) 但是不,您所做的只是定义一个包含 PlayingCard 对象且当前为空的数组。您需要自己实例化和添加对象。
在一个不相关的注释上,也许你可以在你的 public CardDeck(int my_decks)
函数中做这样的事情:cardArray[j+(52*i)].setRank(j+1);
而不是做这个巨大的 if/else 事情......会更具可读性。 【参考方案2】:
根据堆栈跟踪,有问题的行是:
cardArray[(j+(52*i))].setSuit("SPADE");
在 CardDeck.java 中。
我猜这是因为该数组元素的内容为空。虽然您已经定义了数组,但在尝试对其元素调用 .setSuit(...) 之前似乎没有将任何对象放入其中 - 所以您在 null 上调用 .setSuit(...)因此是 NPE。
【讨论】:
用 PlayingCard 类型的对象填充数组的最简单方法是什么? 请原谅我最初用 C++ 编写了这个程序并试图将其转换为 android 不用担心。最简单的方法就是循环添加 PlayingCard 对象。您可以这样做:(为缺少格式而道歉) for(int i=0; i以上是关于Android NullPointerException 导致崩溃的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android 中处理 NullPointerException?
<WebLogicServer; <BEA-000386; <Server subsystem failed. Reason: java.lang.NullPointerExcept
Maven打包时出现“Show Console View”错误弹出框,错误详情为“An internal error has occurred. java.lang.NullPointerExcept
Maven打包时出现“Show Console View”错误弹出框,错误详情为“An internal error has occurred. java.lang.NullPointerExcept