我在Android应用程序中使用Dagger2,我的应用程序中有两个组件。首先是整个应用程序的全局属性,其次是特定于活动实例的属性。

NetComponent.java

@Singleton
@Component(modules = {AppModule.class, NetModule.class})
public interface NetComponent {
    void inject(AuthenticationActivity authenticationActivity);

    void inject(PaymentActivity paymentActivity);
}


ValidationComponent.java

@Singleton
@Component(modules = {ValidatorModule.class})
public interface ValidationComponent {
    void inject(Activity activity);
}


AppModule.java

@Module
public class AppModule {

    private Application application;

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

    @Provides
    @Singleton
    Application providesApplication() {
        return application;
    }
}


NetModule.java

@Module
public class NetModule {

    @Provides
    @Singleton
    SharedPreferences providesSharedPreferences(Application application) {
        return PreferenceManager.getDefaultSharedPreferences(application);
    }

    @Provides
    @Singleton
    Cache provideOkHttpCache(Application application) {
        int cacheSize = 10 * 1024 * 1024; // 10 MiB
        Cache cache = new Cache(application.getCacheDir(), cacheSize);
        return cache;
    }

    @Provides
    @Singleton
    Gson provideGson() {
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
        return gsonBuilder.create();
    }

    @Provides
    @Singleton
    OkHttpClient provideOkHttpClient(Cache cache) {
        OkHttpClient okHttpClient = new OkHttpClient();
        okHttpClient.newBuilder()
                //.addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
                .cache(cache)
                .build();
        return okHttpClient;
    }

    @Provides
    @Singleton
    @Named("authRetrofit")
    Retrofit provideAuthRetrofit(Gson gson, OkHttpClient okHttpClient) {
        Retrofit retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create(gson))
                .baseUrl(PAYMENT_SERVICE)
                .client(okHttpClient)
                .build();
        return retrofit;
    }

    @Provides
    @Singleton
    @Named("paymentRetrofit")
    Retrofit providePaymentRetrofit(Gson gson, OkHttpClient okHttpClient) {
        Retrofit retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create(gson))
                .baseUrl(LOGIN_SERVICE)
                .client(okHttpClient)
                .build();
        return retrofit;
    }


}


ValidatorModule.java

@Module
public class ValidatorModule {

    private final Activity activity;


    public ValidatorModule(Activity activity) {
        this.activity = activity;
    }

    @Provides
    com.mobsandgeeks.saripaar.Validator providesValidator() {
        return new com.mobsandgeeks.saripaar.Validator(activity);
    }
}


AppApplication.java

public class AppApplication extends Application {

    private NetComponent mNetComponent;

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

        mNetComponent = DaggerNetComponent.builder()
                .appModule(new AppModule(this))
                .build();
    }

    public NetComponent getmNetComponent() {
        return mNetComponent;
    }

}


AuthenticationActivity.java

public class AuthenticationActivity extends BaseActivity implements View.OnClickListener, Validator.ValidationListener {

    @Inject
    Validator validator;

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

        ((AppApplication) getApplication()).getmNetComponent().inject(this);

        ValidationComponent validationComponent = DaggerValidationComponent.builder()
                .validatorModule(getValidatorModule())
                .build();

        validationComponent.inject(this);

        ...

        // apply click and validation listeners
        validator.setValidationListener(this);
    }
}

protected ValidatorModule getValidatorModule() {
    return new ValidatorModule(this);
}


它正在生成ValidationComponent,而不是DaggerNetComponent

android - Dagger2未在Android中生成类-LMLPHP

上面是我的模块,我的应用程序的组件。当我编译和构建应用程序时,我遇到了以下错误-

错误

Information:Gradle tasks [clean, :app:generateDebugSources, :app:mockableAndroidJar, :app:prepareDebugUnitTestDependencies, :app:generateDebugAndroidTestSources, :app:compileDebugSources, :app:compileDebugUnitTestSources, :app:compileDebugAndroidTestSources]
C:\Users\xyz\AndroidStudioProjects\ICICIAppathon\app\src\main\java\com\icici\iciciappathon\AppApplication.java
Error:(24, 48) error: cannot find symbol class DaggerNetComponent
C:\Users\xyz\AndroidStudioProjects\ICICIAppathon\app\src\main\java\com\icici\iciciappathon\login\AuthenticationActivity.java
Error:(35, 48) error: cannot find symbol class DaggerValidationComponent
Error:(39, 43) error: package com.icici.iciciappathon.databinding does not exist
C:\Users\xyz\AndroidStudioProjects\ICICIAppathon\app\src\main\java\com\icici\iciciappathon\checkout\PaymentActivity.java
Error:(28, 43) error: package com.icici.iciciappathon.databinding does not exist
C:\Users\xyz\AndroidStudioProjects\ICICIAppathon\app\src\main\java\com\icici\iciciappathon\dashboard\DashboardActivity.java
Error:(32, 43) error: package com.icici.iciciappathon.databinding does not exist
C:\Users\xyz\AndroidStudioProjects\ICICIAppathon\app\src\main\java\com\icici\iciciappathon\shopping\ScanBarcodeActivity.java
Error:(41, 43) error: package com.icici.iciciappathon.databinding does not exist
C:\Users\xyz\AndroidStudioProjects\ICICIAppathon\app\src\main\java\com\icici\iciciappathon\ui\GetStartedActivity.java
Error:(27, 43) error: package com.icici.iciciappathon.databinding does not exist
C:\Users\xyz\AndroidStudioProjects\ICICIAppathon\app\src\main\java\com\icici\iciciappathon\dagger\component\NetComponent.java
Error:(34, 10) error: com.mobsandgeeks.saripaar.Validator cannot be provided without an @Inject constructor or from an @Provides- or @Produces-annotated method.
com.icici.iciciappathon.login.AuthenticationActivity.validator
[injected field of type: com.mobsandgeeks.saripaar.Validator validator]
Error:Execution failed for task ':app:compileDebugJavaWithJavac'.
> Compilation failed; see the compiler error output for details.
Information:BUILD FAILED
Information:Total time: 11.373 secs
Information:9 errors
Information:0 warnings
Information:See complete output in console

最佳答案

这里的一般说法是,Dagger遇到错误时通常不会在绑定图中执行不可能的操作时不生成类。就是这种情况。


  C:\ Users \ xyz \ AndroidStudioProjects \ ICICIAppathon \ app \ src \ main \ java \ com \ icici \ iciciappathon \ dagger \ component \ NetComponent.java
  错误:(34,10)错误:没有@Inject构造函数或@ Provides-或@ Produces-注释方法无法提供com.mobsandgeeks.saripaar.Validator。
  com.icici.iciciappathon.login.AuthenticationActivity.validator
  [类型为com.mobsandgeeks.saripaar.Validator验证器的注入字段]


我同意azizbekian的观点,问题是您正在尝试从AuthenticationActivity内注入Validator,并告诉NetComponent尝试这样做,而不指示其如何这样做(在ValidationModule中)。

在您发布的代码中,没有任何理由让NetComponent注入AuthenticationActivity。没有什么可提供的。因此,您可以删除这两行并完成操作:

// In NetComponent
void inject(AuthenticationActivity authenticationActivity);

// In AuthenticationActivity
((AppApplication) getApplication()).getmNetComponent().inject(this);


但是,也有可能您没有向我们显示AuthenticationActivity中所需的NetComponent依赖关系。在这种情况下,您将需要通过子组件或组件依赖性来组合对象图。您仍然需要删除上面列出的两行,因为在任何情况下NetComponent都不需要注入AuthenticationActivity的依赖项。

子组件

要使用subcomponents进行此操作,只需在NetComponent上构建一个生成器,即可通过该生成器获取ValidationActivity。欢迎您提供一个范围,但不一定需要一个范围,我认为将其添加到组合中可能会造成混淆。届时,您的ValidationComponent将有权访问NetComponent中的所有绑定以及ValidationComponent中列出的所有绑定。尽管值得注意的是,这是通过子组件而不是组件依赖项,但这实际上与阿兹别克人的答案相同。我将在稍后讨论组件依赖性。

// After removing the inject(AuthenticationActivity) call, add this to NetComponent
ValidatorComponent validatorComponent(ValidatorModule validatorModule);

// And call the implementation from AuthenticationActivity
((AppApplication) getApplication()).getmNetComponent()
    .validatorModule(new ValidatorModule(this))
    .inject();


您还需要将ValidationComponent@Component切换到@Subcomponent,并删除@Singleton实例(这很有意义,因为您正在为Android创建的每个AuthenticationActivity实例创建一个新实例。

实际上,这将NetComponent变成了ValidationComponent实例的工厂。 Dagger同时生成两者的代码,因此ValidationComponent可以从NetComponent自动访问其所需的任何内容。但是,以这种方式不可能分别为每个代码生成代码或在没有NetComponent实例的情况下获取ValidationComponent(除非通过将其包含在另一个组件中)。

组件依赖性

Component dependencies的工作方式略有不同。它们是独立的组件,因此可以分别和独立生成。取而代之的是,您可以传入一个接口(通常但不一定是另一个Dagger组件,例如NetComponent),并且每个无参数方法都将成为另一个图中的自动提供者。例如,这意味着您可以从NetComponent列出可用于ValidationComponent的特定依赖项,将dependencies={NetComponent.class}添加到ValidationComponent定义中,然后更改DaggerValidationComponent构建器以调用.netComponent(((AppApplication getApplication()).getmNetComponent())来连接确切的实例。 (类似地,您可以使用该接口的任何实现来执行此操作,无论Dagger是否生成它;这都可以帮助进行测试。)您还需要删除对@Singleton的使用,因为Dagger很难拥有两个单独的组件都声称存在于单例范围内-毕竟必须首先创建一个。

您尚未列出要从NetComponent中使用的确切依赖关系,因此我没有可以显示的示例更改。但是,对于这种情况,无论如何我还是建议使用子组件。绑定更加自动化,您可能不会从组件依赖关系中获得的松散耦合中受益,而且您更接近Dagger's official Android support package的设计,因此以后更容易迁移到该版本。

09-25 20:32