【问题标题】:Android: member variable becoming nullAndroid:成员变量变为空
【发布时间】:2014-09-08 09:44:50
【问题描述】:

我有一个活动 - MainActivity,我在 onCreate(...) 方法中初始化成员变量。然后在 onStart() 和 onStop() 方法中使用此变量。

很简单吧?现在的问题是,从我的用户那里,我开始收到 NullPointerException 崩溃报告,这发生在 onStop() 方法中。

我一直在广泛寻找原因,并且我知道当 android 决定释放内存时静态变量可能会变为空,但是我找不到在 onCreate() 中初始化的成员变量的情况。 代码如下:

public class MainActivity extends ActionBarActivity implements ActionBar.TabListener, SharedPreferences.OnSharedPreferenceChangeListener {
private MySvc mySvc;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);     
    mySvc = DI.i().getMySvc();
    ...
}

@Override
protected void onStart() {
    super.onStart();
    mySvc.start();
}

...

@Override
protected void onStop() {
    super.onStop();
    //here I get NPE
    mySvc.stop();
}
}

}

为了让事情变得更加神秘,我开始仅从某些版本的应用程序中获取此崩溃报告,但是旧版本在 onStart() 和 onStop() 中具有相同的行为。

如有任何提示,我将不胜感激。

编辑:

  • DI.i().getMySvc();从不返回 null,它根据单例模式完成。
  • MySvc 是 POJO,在 DI 类中实例化

【问题讨论】:

  • 看看这个我想这就是你搜索的内容stackoverflow.com/questions/151777/…
  • DI.i().getMySvc(); 是否有可能返回null
  • @subspider 该链接如何应用于这个问题?
  • 检查mySvc = DI.i().getMySvc();是否不为空。
  • DI.i().getMySvc() 永远不会返回 null。我在我的问题中犯了一个错误,我在 onStop() 中得到 NPE 而不是在 onStart() 中。在 onStart() 中,一切都像魅力一样。

标签: android android-activity nullpointerexception instance-variables android-lifecycle


【解决方案1】:

我需要道歉,我发现问题是由我们的代码引起的。从某些版本开始,我们向 onCreate() 方法添加了互联网连接检查,如下所示:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);     
    if (!isInternetConnectionPresent()) {
        return;
    }
    mySvc = DI.i().getMySvc();
...
}

因此,如果用户处于离线状态,他们将获得 NPE,因为变量从未初始化,但调用了 onStop()。 我认为根本原因是错误处理的错误方法。我想要实现的是能够从活动中抛出异常,并拥有能够处理这些异常的通用处理程序。 所以在这种情况下,我会抛出 NoInternetConnectionException 并且处理程序会向用户显示一个有意义的对话框。 另外我想知道抛出异常时是否会调用其他生命周期方法。

【讨论】:

    【解决方案2】:

    根据MySvc 是什么,android VM 可以根据需要选择对它进行 GC。使用 android 的最佳方法是首先检查 null,如果需要,再次实例化它,然后做你想做的事。一直为我工作,没有性能问题。

    【讨论】:

    • VM 只会 GC 无法访问的对象。如果有可以访问的引用,VM 不会 GC 对象。虚拟机当然不会在我们的代码中随机设置对null的引用。
    • 没错,这正是我在这里感到困惑的原因。我暂时解决了这个问题: onStop() 方法中的 DI.i().getMySvc().stop() 。但是我不能指望实例变量在任何时候都为空!?
    • 是的,我知道这一点。但是查询代码中的调用显示 DI.i().getMySvc();我肯定不知道那是做什么的。因此,如果 Code-Apprentice 也不知道,请删除否决票。我清楚地说'取决于 MySvc 是什么'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-09
    • 1970-01-01
    • 2017-03-10
    • 1970-01-01
    • 2012-04-29
    相关资源
    最近更新 更多