Android 很少出现空注入场

Android 很少出现空注入场,android,dependency-injection,dagger-2,Android,Dependency Injection,Dagger 2,很少,当我尝试访问注入的字段时,应用程序会崩溃,因为被访问的字段为空。我没有办法复制它,而且一开始也不应该发生。 你知道为什么会发生这种情况以及如何避免吗 正在片段中注入字段: public class MyFragment extends Fragment { @Inject StubManager mStubManager; .... @Override public void onCreate(@Nullable Bundle savedInstanceSt

很少,当我尝试访问注入的字段时,应用程序会崩溃,因为被访问的字段为空。我没有办法复制它,而且一开始也不应该发生。 你知道为什么会发生这种情况以及如何避免吗

正在片段中注入字段:

public class MyFragment extends Fragment {
    @Inject StubManager mStubManager;
    ....
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Application.getAppComponent().inject(this);
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        ....
        menu.findItem(R.id.item_id)
            .setEnabled(!mStubManager.isRunning());
    }
}
应用程序组件如下所示,并在应用程序类中初始化:

@Singleton
@Component(modules = {
        MyModule.class
})
public interface AppComponent {
    StubManager stubManager();

    void inject(MyFragment target);
}

在调用
super
之前,将
inject
调用移动到
onAttach


如前所述,如果Dagger在大部分时间都成功注入了一个不可为@null的字段,那么它可能不是Dagger bug,而是Android生命周期或Java多线程的bug。我猜前者正在这里发生

虽然我在代码或文档中没有一个毫无疑问的理由,粗略地看一下Android的开源代码和(以及)就可以看出,片段并不能保证被创建,只要操作栏可见,选项菜单就被认为是打开的。如果是这样,那么您将从注入的字段中读取
null
值。您可以通过打开选项菜单(如果您没有使用ActionBar)、使用home按钮或单击通知导航离开您的活动,然后返回到您的活动,这样它就必须重新附加片段并重新创建其选项菜单来测试这一点。如果您启用开发选项“不要保留活动”来模拟内存压力,从而导致您的活动被破坏,这可能会更具可复制性,否则在用户设备上会相对随机且不频繁


我怀疑你的注射可能太晚了:请注意,
dagger.android
的文档建议。这是在片段中执行注入的最早、最一致和推荐的位置,特别是如果片段继承自基本片段类:如果超类在
onCreate
onAttach
中使用任何
@Inject
字段,使用
inject
调用时,这些字段也将是
null

如果您的字段不是
@Nullable
则在匕首注入后将不会是
null
。您应该验证何时以及如何调用注入,因为如果您在注入完成之前访问字段,则该值将为null何时何地?@EpicPandaForce我修改了问题,因此现在应该更清楚了。@DavidMedenjak如果在创建应用程序类时初始化组件时已经注入了片段,我是否可能在注入之前访问该字段?如果是这样的话,复制不是更容易吗?我从来都无法复制,而且很少发生(数十万用户之间有10个崩溃实例),很可能是进程死机后发生的事情。我总是在它们的无参数构造函数中注入片段,如果它是活动的子作用域,那么我总是在
super.onCreate()
之前设置它。你完全正确,唯一的一点是,由于我们应用了某种hack,onPrepareOptionsMenu甚至在onAttach之前被调用。所以我会在那里注射。谢谢:)