0

我正在處理我的第一個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

回答

1

看到你發佈的異常堆棧跟蹤 - 它說,錯誤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