gpt4 book ai didi

android - Dagger - 嵌套注入(inject),有必要调用inject()吗?

转载 作者:太空狗 更新时间:2023-10-29 12:39:30 25 4
gpt4 key购买 nike

我是 Dagger 的新手,在开始时我遇到了一些问题。到目前为止,我的项目结构很简单。我的注入(inject)模块:

@Module(
injects = {GameBoardFragment.class, GameManager.class},
complete = false,
library = true
)

public class GameObjectsProviderModule {
private final Application mApplication;

public GameObjectsProviderModule(Application application){
this.mApplication = application;
}

@Provides
@Singleton
public GameManager provideGameManager(){
return new GameManager();
}

@Provides
public Board getBoard(){
return new Board();
}

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

我的简化自定义应用程序类如下所示:

public class MyApp extends Application {
private static ObjectGraph mApplicationGraph;

@Override public void onCreate() {
super.onCreate();

mApplicationGraph = ObjectGraph.create(new GameObjectsProviderModule(this));
}

public static ObjectGraph getObjectGraph(){
return mApplicationGraph;
}
}

现在,我的 fragment 看起来像这样:

public class GameBoardFragment extends Fragment {

@Inject
GameManager mGameManager;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
MyApp.getObjectGraph().inject(this);

View root = inflater.inflate(R.layout.fragment_game_board, container, false);
findViews(root);
confViews();

return root;
}
}

最后是我的 GameManager 类

public class GameManager  {

@Inject Board mBoard;

public GameManager(){
MyApp.getObjectGraph().inject(this);
}
}

安迪,嘿,它有效!伟大的。但我的问题是为什么在我注释掉这一行的情况下它不起作用:

MyApp.getObjectGraph().inject(this);

我们是否总是明确地调用 inject() 函数来使所有必要的注入(inject)发生在嵌套对象中?看起来不是,如咖啡机示例所示:

https://github.com/square/dagger/tree/master/examples/simple/src/main/java/coffee

为什么我必须在 GameManager 类中调用 inject() 才能使其正常工作?


编辑:

构造函数注入(inject)方法工作得很好。

但为了将来的使用,我尝试运行现场注入(inject),但到目前为止我还没有成功。

我注释掉了模块中的两个@Provide 方法,并使我的 GameManager 看起来像这样:

@Singleton
public class GameManager {

@Inject Board mBoard;

@Inject
public GameManager(){
}
}

和董事会:

public class Board {

@Inject
public Board() {
}
}

然而,mBoard 并没有被实例化。我会尝试更多,我想我会找到合适的解决方案。

最佳答案

您应该使用构造函数注入(inject)(例如 Thermosiphon 所做的),除非必要,否则应避免字段注入(inject)。例如,让您的 GameManagerBoard 作为构造函数参数:

@Singleton
public class GameManager {

private final Board mBoard;

@Inject
public GameManager(final Board board){
mBoard = board;
}
}

Dagger 将使用此构造函数创建 GameManager 的实例(因此有 @Inject 注释),并注意到它需要一个 Board实例。使用 ObjectGraph,它将首先创建一个 Board,然后使用该实例创建 GameManager。如果这样做,您可以删除 @Provides GameManager 方法。

在您的例子中,您的模块中有一个@Provides Board 方法。如果您将 @Inject 注释添加到您的 Board 构造函数,您可以从您的模块中删除此提供方法:

public class Board {

@Inject
public Board() {
}
}

如果你不想使用构造函数注入(inject),问题是你告诉 Dagger 你想自己创建你的 GameManager 实例(因为你有 @Provides GameManager方法)。如果你删除这个方法,让 Dagger 像上面那样为你创建它,但在构造函数中没有 Board 参数,Dagger 也会注意到 @Inject Board 字段并注入(inject)它


最后的评论。删除 library = truecomplete = false 语句!在这个例子中这些都不是必需的。只有当你真的知道自己在做什么时才添加它们。如果没有它们,Dagger 将创建编译时错误以通知您出现问题。如果您确实包含了它们,您就是在告诉 Dagger“嘿,我知道我在做什么,别担心,这一切都是正确的”,但实际上并非如此。


编辑

引自 Dagger1 网站:

If your class has @Inject-annotated fields but no @Inject-annotated constructor, Dagger will use a no-argument constructor if it exists. Classes that lack @Inject annotations cannot be constructed by Dagger.

我不经常使用这种方法,所以我可能是错的。我认为这意味着您应该从构造函数中删除 @Inject 注释,如下所示:

@Singleton
public class GameManager {

@Inject Board mBoard;

public GameManager(){ // Or remove the constructor entirely since it's empty
}
}

由于 Board 字段上有一个 @Inject 注释,Dagger 将知道使用无参数构造函数。

关于android - Dagger - 嵌套注入(inject),有必要调用inject()吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28330117/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com