首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >理解Dagger 2 @Component.Builder注释

理解Dagger 2 @Component.Builder注释
EN

Stack Overflow用户
提问于 2017-09-13 12:19:17
回答 3查看 8.8K关注 0票数 16

我正在阅读伟大的教程,该教程解释了@Component.Builder如何在Dagger 2中工作。作者做得很好,这篇文章写得很直接,但我仍有一些困惑需要澄清: Dagger 2的默认实现如下所示:

构成部分:

代码语言:javascript
运行
复制
@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {

  void inject(MainActivity mainActivity);
  SharedPreferences getSharedPrefs();
}

模块:

代码语言:javascript
运行
复制
@Module
 public class AppModule {

    Application application;

    public AppModule(Application application) {
       this.application = application;
    }

    @Provides
    Application providesApplication() {
       return application;
    }
    @Provides
    @Singleton
    public SharedPreferences providePreferences() {
        return application.getSharedPreferences(DATA_STORE,
                              Context.MODE_PRIVATE);
    }
}

组件实例化:

代码语言:javascript
运行
复制
DaggerAppComponent appComponent = DaggerAppComponent.builder()
         .appModule(new AppModule(this)) //this : application 
         .build();

根据本文,通过避免使用@Component.Builder@BindsInstance注释将参数传递给模块构造函数,我们可以进一步简化该代码,然后代码将如下所示:

构成部分:

代码语言:javascript
运行
复制
@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {
   void inject(MainActivity mainActivity);
   SharedPreferences getSharedPrefs();

   @Component.Builder
   interface Builder {
      AppComponent build();
      @BindsInstance Builder application(Application application);      
  }

}

模块:

代码语言:javascript
运行
复制
@Module
 public class AppModule {

     @Provides
     @Singleton
     public SharedPreferences providePreferences(
                                    Application application) {
         return application.getSharedPreferences(
                                    "store", Context.MODE_PRIVATE);
     }
 }

并实例化以下组件:

代码语言:javascript
运行
复制
DaggerAppComponent appComponent = DaggerAppComponent.builder()
           .application(this)
           .build();

我几乎能理解上面的代码是如何工作的,但是我不明白的部分是:当我们实例化组件时,我们是如何从appModule(new AppModule(this))application(this)的?

我希望这个问题是明确的,谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-09-13 12:37:16

tl; Dagger博士将创建任何非arg构造函数本身,如果您不传递它们,那么@BindsInstance的使用可能比从模块中提供类型更好。

首先,您有一个组件,它需要构造一个Application。因此,构建模块并将其传递给组件。

现在,使用组件生成器,您只需将单个对象绑定到组件。这是我们上面所做的另一种选择。不再需要模块,我们可以直接将Dagger交给组件中我们想要的对象。

就像使用@Binds提供接口实现一样,您通常可以假设Dagger能够并将比使用模块的简单方法更好地优化特性,因为它的意图更加明确。

因此,使用@BindsInstance将类型添加到组件中,这样我们就不再需要模块来提供它了。现在,我们还可以从模块构造函数中删除该参数。

当我们实例化组件时,我们是如何从AppModule(新AppModule(this))到应用程序(This)的?

因为Dagger可以实例化无args模块本身,所以不再需要显式地将模块添加到组件中,我们可以用新的.application(this)调用替换这一行。

票数 21
EN

Stack Overflow用户

发布于 2018-02-15 11:18:40

代码语言:javascript
运行
复制
 @Component.Builder
   interface Builder {
      AppComponent build();
      @BindsInstance Builder application(Application application);      
  }

当我们调用该方法时

申请(申请申请)

来自应用程序类

.application(这个)

它将把我们的应用程序对象设置为AppComponent。因此,在应用程序组件内部,应用程序实例是可用的。

因此,我们可以从应用程序模块中删除以下代码,因为dagger将在任何需要的地方自动注入应用程序实例。

代码语言:javascript
运行
复制
Application application;
   public AppModule(Application application) {
       this.application = application;
    }

    @Provides
    Application providesApplication() {
       return application;
    }

此外,Dagger用默认构造函数实例化所有模块。

如果您想要AppModule中的上下文对象,只需编写

代码语言:javascript
运行
复制
@Module
public class AppModule {

   @Provides
    Context provideContext(Application application) {
        return application;
    }
}
票数 7
EN

Stack Overflow用户

发布于 2022-10-19 05:46:21

* >> --我发现了这样的错误:

“AppComponent appComponent =appComponent "

遵循下面的步骤

  1. 从import部分删除该行"import com.joiibmed.Dagger2.DaggerAppComponent;“。
  2. 运行App,它将再次给出同样的错误。
  3. 此时,转到导入错误出现的函数。你得到了对“导入类”的建议
  4. 再次运行应用程序。解决了。

☻♥完成保持代码

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46197410

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档