极少出现空注入场

时间:2017-06-07 08:29:03

标签: android dependency-injection dagger-2

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

该字段正在片段中注入:

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);
}

1 个答案:

答案 0 :(得分:2)

在致电inject之前,将onAttach来电转移至super

正如David提到in the comments,如果你有一个非@Nullable字段,Dagger大部分时间成功注入,那么它可能不是Dagger bug,而是Android生命周期或Java多线程。我猜测前者正在这里发生。

虽然我在代码或文档中没有毫无疑问的原因,anecdotally there seem to be cases where the options menu is prepared before onCreate,并粗略地浏览了FragmentManagerActivity的Android开源代码(以及menu docs)表示只要操作栏可见,就不能保证创建Fragment并且选项菜单被认为是打开的。如果是这样,那么您将从注入的字段中读取null值。您可以通过打开选项菜单(如果您没有使用ActionBar),使用主页按钮或单击通知离开您的活动,然后返回到您的活动以使其必须重新附加片段并重新创建其选项菜单。如果您启用开发选项“不要保持活动”来模拟可能导致您的活动被销毁的内存压力,这可能会更加可重现,否则这些活动会在用户的设备上相对随机且不常见。

我怀疑您的注射可能只是发生迟到:请注意onAttach is called before onCreate is called,以便dagger.android的文档建议injecting in onAttach before the call to super.onAttach。这是在Fragments中执行注入的最早,最一致和推荐的地方,特别是如果您的Fragment继承自基础Fragment类:如果超类具有@InjectonCreate中使用的任何onAttach字段{1}},您null的{​​{1}}来电也是inject