我有2个模块:AndroidModule用于提供Context相关的对象,而PhotosModule提供PhotoManager

我想在PhotoManager中使用PhotosFragmentPhotoManager取决于DbManager,由AndroidModule提供。

如何连接所有点?

代码可以编译,但是在此行上将引发NPE:

mDbManager.readDatabase();


表示即使我设置了DbManager,也不会发生将PhotoManager注入AndroidModule

injects = PhotoManager.class


mDbManager中。

另外,PhotoManager不是私有字段,因此我认为我不必在的构造函数上使用注入。现场注入应足够。

是什么原因,我如何满足缺少的依赖关系?我认为我的代码可能存在多个问题。注意:我刚开始使用Dagger,请记住这一点。

应用:

public class TestApp extends Application {

    private ObjectGraph mObjectGraph;

    @Override
    public void onCreate() {
        super.onCreate();
        mObjectGraph = ObjectGraph.create(getModules().toArray());
    }

    protected List<Object> getModules() {
        return Arrays.asList(new AndroidModule(this), new PhotosModule());
    }

    public void inject(Object object) {
        mObjectGraph.inject(object);
    }
}


AndroidModule:

@Module(library = true, injects = PhotoManager.class)
public class AndroidModule {

    private final TestApp mApplication;

    public AndroidModule(TestApp application) {
        mApplication = application;
    }

    @Provides
    @Singleton
    @ForApplication
    Context provideApplicationContext() {
        return mApplication;
    }

    @Provides
    @Singleton
    DbManager provideDbManager() {
        return new DbManager(mApplication);
    }
}


图片模块:

@Module(injects = PhotosFragment.class)
public class PhotosModule {

    @Provides
    @Singleton
    PhotoManager providePhotoManager() {
        return new PhotoManager();
    }
}


PhotoManager:

@Singleton
public class PhotoManager {

    @Inject
    DbManager mDbManager;

    public void doSomething() {
        mDbManager.readDatabase();
    }
}


照片片段:

public class PhotosFragment extends Fragment {

    @Inject
    PhotoManager mPhotoManager;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ((TestApp) getActivity().getApplication()).inject(this);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        ///...
        mPhotoManager.doSomething();
    }
}


DbManager:

@Singleton
public class DbManager {

    public DbManager(Context context) {
        //...
    }

    public void readDatabase() {
        //...
    }
}

最佳答案

这是问题的核心:在PhotosModule中,您有provider方法:

PhotoManager providePhotoManager() {
    return new PhotoManager();
}


您正在自己new组装PhotoManager,因此Dagger没有机会注入其依赖项(DbManager)。

我认为这是因为您误解了injects@Module(injects=...)注释上的AndroidModule属性的含义。你有:

@Module(library = true, injects = PhotoManager.class)


但是不需要injects,因为您永远不会在PhotoManager上调用objectGraph.inject。相反,您只注入了PhotoFragment,这是正确的...

因此,解决NPE问题的一种方法是:


injects=PhotoManager.class中删除​​AndroidModule.java

@Module(library = true)

更改PhotosModule以包括AndroidModule

@Module(injects = PhotosFragment.class, includes = AndroidModule.class)

我避免使用@Inject注释进行字段注入(仅将其用于顶级对象,即在其中执行objectgraph.inject的位置,例如活动和片段级别),并使用构造函数注入代替所有其他依赖项。因此,我将更改PhotoManager像这样注入DbManager

private final DbManager mDbManager;

public PhotoManager(DbManager dbManager) {
    mDbManager = dbManager;
}



我已经放置了代码here on GitHub

09-25 21:44