2011-10-24 29 views
0

注意:此標題已更改以更好地反映實際問題。繼承的OnCreate中的NullPointerException活動

我碰到一個棘手的NullPointerException - 希望有人能在這裏給我一個想法,以什麼錯誤,因爲我不是成功地重新創建的錯誤,這樣我可以得到一個調試堆棧跟蹤。

開發人員儀表板中的堆棧跟蹤都表明應用程序正在從Activity子類中引發OnCreate中的NullPointerException(例如,我有AActivity和BActivity都從引發異常的BaseActivity繼承)。推測這是在應用程序被丟失後恢復時發生的 - 至少這是我最好的猜測。儘管一位用戶報告在啓動應用程序時立即出現此錯誤。

的功能的onCreate如下所示:

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     this.camp_ = MyApplication.getInstance().camp(); 
     if (this.camp_ == null) { 
      this.finish(); 
      return; 
     } 
     if (!this.camp_.isSane()) { 
      this.finish(); 
      return; 
     } 
    } 

這是本質的。 MyApplication是應用程序的應用程序; getInstance返回一個指向實例的指針,如果實例爲null,則拋出IllegalStateException。 isSane()主要檢查this.camp_中的某些變量是否爲空,如果是後者,則返回false。

我不能爲我的生活看到這可以拋出一個NullPointerException,但是......它顯然是。這是我目前錯誤報告的最常見原因 - 但我至今沒有任何運氣可以自己挑起這個問題(我經常遇到的問題是這些錯誤只發生在應用程序從內存中擦除後重新啓動)。

[編輯1]

例堆棧跟蹤:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.michael.android.app/com.michael.android.app.gui.GreetActivity}: java.lang.NullPointerException 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:123) 
at android.app.ActivityThread.main(ActivityThread.java:4627) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:521) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.NullPointerException 
at com.michael.android.app.gui.BaseActivity.onCreate(Unknown Source) 
at com.michael.android.app.gui.GreetActivity.onCreate(Unknown Source) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
... 11 more 

如前所述BaseActivity是繼承,所以有堆棧跟蹤的這個相同的基本圖案的幾個變體。 onResume基本上對this.camp_對象的有效性進行同樣的檢查 - 在BaseActivity中沒有onDestroy或onPause代碼。

[編輯2]

的GetInstance代碼如下:

public static MyApplication getInstance() { 
    checkInstance(); 
    return instance_; 
} 

private static void checkInstance() { 
    if (instance_ == null) 
     throw new IllegalStateException("MyApplication not created yet!"); 
} 

如果實例爲null,它應該返回一個IllegalStateException,而不是NPE。

不確定這是否相關,但這裏是Application類的一個片段。

[編輯3]

public class MyApplication extends Application { 
    // Instance 
    private static MyApplication instance_ = null; 
    private Camp camp_ = null; 

    public static MyApplication getInstance() { 
     checkInstance(); 
     return instance_; 
    } 

    private static void checkInstance() { 
     if (instance_ == null) 
      throw new IllegalStateException("MyApplication not created yet!"); 
    } 


    // Campaign 
    public Camp camp() { 
     return this.camp_; 
    } 

    private void parseSettings() { 
     if (getFileStreamPath("settings.xml").exists()) { 
      InputStream istream = null; 
      try { 
       istream = openFileInput("settings.xml"); 
       /* Get a SAXParser from the SAXPArserFactory. */ 
       SAXParserFactory spf = SAXParserFactory.newInstance(); 
       SAXParser sp = spf.newSAXParser(); 
       /* Get the XMLReader of the SAXParser we created. */ 
       XMLReader xr = sp.getXMLReader(); 
       /* Create a new ContentHandler and apply it to the XML-Reader */ 
       SettingsHandler handler = new SettingsHandler(); 
       xr.setContentHandler(handler); 
       xr.parse(new InputSource(istream)); 
      } catch (FileNotFoundException e) { 
       Log.e("MyApplication", "File not found exception: settings.xml"); 
      } catch (Exception e) { 
       Log.e("MyApplication", "Exception thrown when decoding file settings.xml"); 
       e.printStackTrace(); 
      } 
     } 
    } 

    public void saveSettings() { 
     // ... 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     // Set the instance 
     instance_ = this; 
     BaseActivity.flurryId = flurryId; 
     parseSettings(); 
    } 

    public void setCamp(Camp c) { 
     this.camp_ = c; 
    } 

} 

我想知道如果這個問題可能有一些與此基準是在OnCreate方法莫名其妙不正確。

+0

我認爲null是'MyApplication.getInstance()'。 – Cristian

+0

但是,如果getInstance()在if(instance_ == null)拋出新的IllegalStateException(「MyApplication not created yet」)時它怎麼能爲null呢?這對我來說毫無意義。 :-( –

回答

0

請注意,我有一個BaseActivity(這是NPE發生的地方),它將由AActivity和BActivity繼承。

顯然,問題是在BaseActivity的onCreate中調用「finish()」。將finish()調用移出BaseActivity onCreate調用,而是檢查是否在AActivity中調用finish()並且BActivity修復了問題。

希望這對其他人有用。我會改變標題以更好地反映實際問題。

0

難道你至少沒有堆棧跟蹤報告嗎?你在談論NPE,但實際上並不是它拋出的地方。當然你提出受影響的代碼?

我的猜測是你依賴於以前活動的一些代碼,但是由於你的應用程序被恢復了,以前的活動沒有實例化,數據是null。所以我建議在onDestroy中搜索這樣的數據相關代碼,因爲它也會被調用。

+0

增加了一個堆棧跟蹤的例子 –

+0

啊,好吧,現在我開始明白你的意思了,我會繼續看看(但是現在是時候趕上一些睡眠;-) – Knickedi

1

在此代碼中,只有返回null的MyApplication.getInstance()會導致NullPointerException。如果您想要更詳細的解釋,請提供堆棧跟蹤和MyApplication Singleton代碼。

我不知道你爲什麼要在MyApplication類上實現Singleton模式。你的應用程序只運行一次,所以不需要Singleton。如果要在活動中訪問應用程序實例,可以使用 MyApplication application =(MyApplication)getApplication();

+0

正如我回答對於Cristian,我看不出這是怎麼可能的。添加來自MyApplication的getInstance代碼 –

+1

關於第二點;方便/個人偏好。我發現MyApplication.getInstance()更易於在代碼中讀取和使用 - 並且getApplication ()並不真正有用,如果你必須得到應用程序而不直接訪問Context。 –

+0

非常棘手的問題,我想你有一個Singleton模式的觀點(見http://androidcookbook.com/Recipe.seam?recipeId = 1218) – MarcFasel