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

Activity seems to be created before application object

我在 Play 商店中收到了一些崩溃报告,起初我觉得这很疯狂。 由于 NullPointerException,一些活动(在一种情况下,它是广播接收器)在 onCreate()/onResume() 中崩溃。

这些活动使用静态方法,这些方法又使用应用程序单例[用于上下文],但是对象 returned 为空,就像应用程序对象根本不存在一样。根据我的理解,应用程序应该始终有一个实例。

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

从活动调用时,MyApplication.getInstance() return 怎么可能为空?我不知道怎么会这样。

当然,我无法重现这次崩溃。 这主要发生在 Android 6,但我有一些来自 Android 8 和 9 的报告。

我猜你正在做这个 question 中投票最多的答案。 但是,你应该看到很多人在评论中警告的内容:

The downside is that there is no guarantee that the non-static onCreate() will have been called before some static initialization code tries to fetch your Context object. That means your calling code will need to be ready to deal with null values which sort of defeats the whole point of this question. – Melinda Green

.

It's upsetting to see how many upvotes this answer has. You should never hold a static instance to context - for proofs sake, try using Leak Canary (github.com/square/leakcanary) and find the memory leak caused because of this. @people-with-enouhg-rep-and-Android-knowledge, please re-review this answer and act accordingly. This is guaranteed to be used by beginners and it's plain simple wrong. – Crearo Rotar

您应该:

  • 尽可能使用您的 Activity 上下文并将其传递给需要它的任何其他 class。
  • 或者,我真正推荐的是,使用 Dagger2 设置依赖注入。刚开始学起来有点困难,但是有很多信息和教程可以帮助您入门。一旦你正确设置了 Dagger,你需要以空安全的方式访问你的应用程序上下文就是将它注入相应的 class 中,如下所示:

    public class MyClass {
    
        @Inject
        Context context;
    
    
        ...
    
    }
    

作为关于匕首依赖注入的其他答案的替代方案,我只想举一个从 activity 获取上下文的老式方法的例子。如果您将上下文声明为成员变量,它将在您的整个 activity 中可用,并且可以根据需要传递给其他 类:

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 auto restore not initializing app 中,问题是一样的,他们确定原因是在 Android 6 中引入的自动备份功能。基本上,从备份恢复后,应用程序以一种奇怪的方式重新启动,在 Activity 之前未创建应用程序对象。我们现在可以重现问题并禁用备份修复问题。