从java.lang.NullPointerException中读取对象时,Android应用程序在启动时崩溃

问题描述:

我正在处理我的第一个Android应用程序。它工作正常,直到我决定添加一个功能来保存和加载OnCreate和onRestart上的对象和设置。之后,应用程序在启动时崩溃。这是我从OnCreate调用的setSettings。从java.lang.NullPointerException中读取对象时,Android应用程序在启动时崩溃

public void setSettings(){ 
    SharedPreferences settings = getSharedPreferences("Prefs",0); 
    newGame = settings.getBoolean("newGame", true); 
    autoDecide = settings.getBoolean("autoDecide", true); 
    saved = settings.getBoolean("saved", false); 
    if (saved){  
     player1 = readPlayer("Player 1"); 
     player2 = readPlayer("Player 2"); 
     ((TextView)findViewById(R.id.Player1name)).setText(""+player1.name); 
     ((TextView)findViewById(R.id.Player2name)).setText(""+player2.name); 
     ((TextView)findViewById(R.id.player1wins)).setText(""+player1.totalWins); 
     ((TextView)findViewById(R.id.player2wins)).setText(""+player2.totalWins); 
     ((TextView)findViewById(R.id.Player1life)).setText(""+player1.life); 
     ((TextView)findViewById(R.id.Player2life)).setText(""+player2.life); 
    } 
} 

保存布尔应该是假的,直到我保存的东西,但我不认为这是工作。这是readPlayer,它会调用问题的出现位置。

public Player readPlayer(String loc) { 
    //FileInputStream fis; 
     try { 
     BufferedInputStream buf = new BufferedInputStream(openFileInput(loc)); 
     ObjectInputStream stream = new ObjectInputStream(buf); 
     Player re = (Player) stream.readObject(); 
     stream.close(); 
     buf.close(); 
     return re; 
     } catch (FileNotFoundException e) { 
     //e.printStackTrace(); 
      return new Player(loc); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 
    return new Player(loc); 
} 

这里是我在碰撞时得到的logCat。

05-26 03:49:05.739: E/AndroidRuntime(391): java.lang.RuntimeException: Unable to start activity ComponentInfo{jjcard.app.lifecount/jjcard.app.lifecount.Life_counterActivity}: java.lang.NullPointerException 
05-26 03:49:05.739: E/AndroidRuntime(391): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1815) 
05-26 03:49:05.739: E/AndroidRuntime(391): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1831) 
05-26 03:49:05.739: E/AndroidRuntime(391): at android.app.ActivityThread.access$500(ActivityThread.java:122) 
05-26 03:49:05.739: E/AndroidRuntime(391): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1024) 
05-26 03:49:05.739: E/AndroidRuntime(391): at android.os.Handler.dispatchMessage(Handler.java:99) 
05-26 03:49:05.739: E/AndroidRuntime(391): at android.os.Looper.loop(Looper.java:132) 
05-26 03:49:05.739: E/AndroidRuntime(391): at android.app.ActivityThread.main(ActivityThread.java:4123) 
05-26 03:49:05.739: E/AndroidRuntime(391): at java.lang.reflect.Method.invokeNative(Native Method) 
05-26 03:49:05.739: E/AndroidRuntime(391): at java.lang.reflect.Method.invoke(Method.java:491) 
05-26 03:49:05.739: E/AndroidRuntime(391): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841) 
05-26 03:49:05.739: E/AndroidRuntime(391): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599) 
05-26 03:49:05.739: E/AndroidRuntime(391): at dalvik.system.NativeStart.main(Native Method) 
05-26 03:49:05.739: E/AndroidRuntime(391): Caused by: java.lang.NullPointerException 
05-26 03:49:05.739: E/AndroidRuntime(391): at jjcard.app.lifecount.Life_counterActivity.setSettings(Life_counterActivity.java:72) 
05-26 03:49:05.739: E/AndroidRuntime(391): at jjcard.app.lifecount.Life_counterActivity.onCreate(Life_counterActivity.java:42) 
05-26 03:49:05.739: E/AndroidRuntime(391): at android.app.Activity.performCreate(Activity.java:4397) 
05-26 03:49:05.739: E/AndroidRuntime(391): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048) 
05-26 03:49:05.739: E/AndroidRuntime(391): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1779) 

我不知道,如果你需要的玩家创造,但在这里它是

public Player(String nameN){ 
    name = nameN; 
    life = 8000; 
    totalWins = 0; 
    totalLosses = 0; 
    wins = new HashMap<String, Integer>(); 
} 

它发生,每次我启动它,我已经尝试了一些东西,你很可能会看到由代码没有成功。我试着四处搜寻,但找不到任何东西。希望你们能帮忙。
编辑:这里是第72行LogCat显示是问题。

((TextView)findViewById(R.id.Player1name)).setText(""+player1.name); 

所以看起来你是对的,它可能会读取一个空的对象,而不是像我认为的那样返回一个新的播放器。 而且因为我不知道很多有关使写作和阅读的对象,我只是用defaultWriteObject和defaultReadObject

private void writeObject(ObjectOutputStream out) throws IOException{ 
    out.defaultWriteObject(); 
} 
private void readObject(ObjectInputStream in) throws ClassNotFoundException, IOException{ 
    in.defaultReadObject(); 
} 

编辑:改变读/写,并试图以检查名称为空后,它仍然不起作用。我甚至试图将文本设置为一个字符串,它仍然给出一个nullPointerException,所以猜测它有一些与FindViewById(R.id.Player1name),但我不知道到底是什么。我使用ViewPagerIndicator为不同的屏幕使用不同的视图,这可能与它有关吗?

+0

Life_counterActivity.java见线72号 –

+0

什么是上线72? – barry

看到你发布的异常堆栈跟踪 - 它说,错误Life_counterActivity.javacaused by:线#72 - 这会给你一些指示为可能是null的对象。

不知道哪一行它实际上是,它可能是6号线看起来像这样的一个...

((TextView)findViewById(R.id.Player1name)).setText(""+player1.name); 

有两种可能性...

  1. 对象player1是空的,所以你不能要求它的name
  2. 找不到R.id.Player1name - 这是不太可能的,但如果它确实返回空对象,则不能调用setText()

看到,因为尽管它可能player1player2,你可以请出示你在哪里保存Player对象的文件 - 它看起来像它可能创建该文件中的对象,但没有填充的变量。假设Player执行Serializable,您能否显示writeObject()readObject()的代码。有关这些方法的信息,请参阅Serializable java doc

所以,建议您readObject()writeObject()方法...

private void writeObject(ObjectOutputStream out) throws IOException{ 
    out.writeObject(name); 
    out.writeInt(life); 
    out.writeInt(totalWins); 
    out.writeInt(totalLosses); 
    out.writeObject(wins); 
} 
private void readObject(ObjectInputStream in) throws ClassNotFoundException, IOException{ 
    name = (String)in.readObject(); 
    life = in.readInt(); 
    totalWins = in.readInt(); 
    totalLosses = in.readInt(); 
    wins = (HashMap<String, Integer>) in.readObject(); 
} 
+0

好的,我添加了你问的问题,谢谢你的帮助。 – jjcard

+0

所以,我建议你写你自己的'readObject()'和'writeObject()'方法。我编辑了我的答案,包含一个建议的解决方案,它写出每个值,并再次读取它们。我使用“ObjectInputStream”和“ObjectOutputStream”java文档顶部的摘要中显示的示例构建了这个示例。 – wattostudios

+0

感谢您的建议,但它仍然在启动时崩溃。我认为我缩小了问题的范围,不是关于播放器对象或player.name为空,而是(((TextView)findViewById(R.id.Player1name)) – jjcard