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