活动似乎是在应用程序对象之前创建的

时间:2019-04-09 17:09:44

标签: android crash android-lifecycle application-lifecycle

我一直在Play商店收到一些当机报告,这些报告最初对我来说似乎很疯狂。 由于NullPointerException,某些活动(在一种情况下,它是广播接收器)在onCreate()/ onResume()中崩溃。

这些活动正在使用静态方法,这些方法又使用Application单例[for context],但是返回的对象为null,就像应用程序对象根本不存在一样。据我了解,该应用程序应始终具有一个实例。

我的代码很普通,应用程序在其onCreate()中设置一个静态字段,活动调用的类使用MyApplication.getInstance()来返回应用程序对象。

从活动中调用MyApplication.getInstance()如何返回null?我不知道怎么回事。

当然,我无法复制此崩溃。 这主要发生在Android 6中,但是我有一些来自Android 8和9的报告。

3 个答案:

答案 0 :(得分:2)

我想您正在做question中投票率最高的答案。 但是,您应该在评论中看到很多人警告的内容:

  

缺点是不能保证非静态   在进行一些静态初始化之前,将调用onCreate()。   代码尝试获取您的Context对象。这意味着您的调用代码   将需要准备好应对失败的空值   这个问题的重点。 –梅琳达·格林

  

很高兴看到这个答案有多少票。 您永远不要在上下文中保存静态实例-为证明起见,请尝试使用Leak Canary(github.com/square/leakcanary)并查找由此引起的内存泄漏。 @ people-with-enouhg-rep-and-Android-knowledge,请重新查看此答案并采取相应措施。保证初学者可以使用它,这是简单的错误。 – Crearo Rotar

您应该:

  • 尽可能使用您的Activity上下文,并将其传递给需要它的任何其他类。
  • 或者,我真正建议使用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对象。现在,我们可以重现该问题,并禁用备份可以解决该问题。