2011-10-24 30 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