继承Activity的OnCreate中的NullPointerException

时间:2011-10-24 22:34:20

标签: android

注意:更改了标题以更好地反映实际问题。

我遇到了一个棘手的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_中的某些变量是否为null,如果是后者则返回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!");
}

如果instance为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方法中某种程度上是不正确的。

3 个答案:

答案 0 :(得分:1)

在此代码中,仅MyApplication.getInstance()返回null将导致NullPointerException。如果您想要更详细的解释,请提供stacktrace和MyApplication Singleton代码。

我不确定为什么要在MyApplication类上实现Singleton模式。您的应用程序只运行一次,因此不需要Singleton。如果要在可以使用的活动中访问应用程序实例     MyApplication application =(MyApplication)getApplication();

答案 1 :(得分:0)

你至少没有堆栈跟踪报告吗?你在谈论NPE,但实际上并不是它被抛出的地方。当然你出示受影响的代码?

我的猜测是你依赖以前活动中的一些代码,但是由于你的应用程序已经恢复,之前的活动没有实例化,数据是null。所以我建议在onDestroy中搜索这样的数据相关代码,因为它也会被调用。

答案 2 :(得分:0)

请注意,我有一个BaseActivity(发生NPE的地方),它将由AActivity和BActivity继承。

显然,问题是在onAreate of BaseActivity中调用“finish()”。移动finish()调用BaseActivity onCreate调用,而不是检查是否在AActivity中调用finish(),BActivity修复了问题。

希望这对其他人有用。我会更改标题以更好地反映实际问题。