我一直在Play商店收到一些当机报告,这些报告最初对我来说似乎很疯狂。 由于NullPointerException,某些活动(在一种情况下,它是广播接收器)在onCreate()/ onResume()中崩溃。
这些活动正在使用静态方法,这些方法又使用Application单例[for context],但是返回的对象为null,就像应用程序对象根本不存在一样。据我了解,该应用程序应始终具有一个实例。
我的代码很普通,应用程序在其onCreate()中设置一个静态字段,活动调用的类使用MyApplication.getInstance()来返回应用程序对象。
从活动中调用MyApplication.getInstance()如何返回null?我不知道怎么回事。
当然,我无法复制此崩溃。 这主要发生在Android 6中,但是我有一些来自Android 8和9的报告。
答案 0 :(得分:2)
我想您正在做question中投票率最高的答案。 但是,您应该在评论中看到很多人警告的内容:
缺点是不能保证非静态 在进行一些静态初始化之前,将调用onCreate()。 代码尝试获取您的Context对象。这意味着您的调用代码 将需要准备好应对失败的空值 这个问题的重点。 –梅琳达·格林
。
很高兴看到这个答案有多少票。 您永远不要在上下文中保存静态实例-为证明起见,请尝试使用Leak Canary(github.com/square/leakcanary)并查找由此引起的内存泄漏。 @ people-with-enouhg-rep-and-Android-knowledge,请重新查看此答案并采取相应措施。保证初学者可以使用它,这是简单的错误。 – Crearo Rotar
您应该:
或者,我真正建议使用Dagger2设置依赖项注入。一开始学习起来有点困难,但是有很多信息和教程可以帮助您入门。正确设置Dagger之后,以null安全的方式访问Application上下文所需要做的就是将其注入相应的类中,如下所示:
public class MyClass {
@Inject
Context context;
...
}
答案 1 :(得分:0)
作为有关匕首依赖注入的其他答案的替代方案,我只想举一个示例,以一种老式的方式从活动中获取上下文。如果将上下文声明为成员变量,它将在整个活动中可用,并可根据需要传递给其他类:
public class ExampleActivity extends AppCompatActivity {
private Context mContext;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_example);
mContext = this;
}
答案 2 :(得分:0)
我想我找到了原因。在Android 6自动还原未初始化的应用程序中,问题是相同的,他们将原因确定为Android 6中引入的自动备份功能。基本上,从备份还原后,应用程序以一种奇怪的方式重新启动,其中在活动之前未创建Application对象。现在,我们可以重现该问题,并禁用备份可以解决该问题。