Dagger 2 “Dagger” prefix component not able to compile? auto generated class

前端 未结 8 3517
悲哀的现实
悲哀的现实 2021-02-20 18:44

Im trying to use Dagger 2 on android. I previously had it working and i had an appModule injecting dependencies into specific classes in the app. My Issue is that iam getting th

8条回答
  •  独厮守ぢ
    2021-02-20 19:28

    I was having a similar issue with Dagger 2. I had an AppComponent and an ActivityComponent (being a subcomponent). And as soon as I would add a new inject() function in the AppComponent, I would get the above errors.

    There was more errors besides the 'cannot find symbol' error but they were very vague and I couldn't debug my issues. After digging and researching stackoverflow and different tutorials, I realized I was using Dagger incorrectly. Specifically the way my AppComponent and ActivityComponent was setup.

    I was under the assumption that I could inject my 'Activity' or 'Fragment' with both my AppComponent and ActivityComponent. This turned out to be wrong, at least I found out that it wasn't the right way of using Dagger.

    My Solution:

    AppComponent

    @Singleton
    @Component(modules = {AppModule.class})
    public interface AppComponent {
    
        void inject(MyApp application);
        void inject(ContextHelper contextHelper);
    
        // for exports
        MyApp application();
        PrefsHelper prefsHelper();
    }
    

    App Module

    @Module
    public class AppModule {
    
        private final MyApp application;
    
        public AppModule(MyApp application) {
    
            this.application = application;
        }
    
        @Provides @Singleton
        public MyApp application() {
    
            return this.application;
        }
    
        @Provides @Singleton
        public PrefsHelper providePrefsHelper() {
    
            PrefsHelper prefsHelper = new PrefsHelper(application);
            return prefsHelper;
        }
    }
    

    ActivityComponent

    @ActivityScope
    @Component (dependencies = {AppComponent.class}, modules = {ActivityModule.class})
    public interface ActivityComponent {
    
        void inject(MainActivity activity);
        void inject(OtherActivity activity);
        void inject(SomeFragment fragment);
    }
    

    ActivityModule

    @Module
    public class ActivityModule {
    
        private final MyActivity activity;
    
        public ActivityModule(MyActivity activity) {
    
            this.activity = activity;
        }
    
        @Provides @ActivityScope
        public ContextHelper provideContextHelper(MyApp application) {
    
            // My ContextHelper depends on certain things from AppModule 
            // So I call appComponent.inject(contextHelper)
    
            AppComponent appComponent = application.getAppComponent();
            ContextHelper contextHelper = new ContextHelper(activity);
            appComponent.inject(contextHelper);
            return contextHelper;
        }
    }
    

    Application

    public class MyApp extends Application {
    
        private AppComponent appComponent;
    
        @Override
        public void onCreate() {
    
            super.onCreate();
            initializeDepInj();
        }
    
        private void initializeDepInj() {
    
            appComponent = DaggerAppComponent.builder()
                    .appModule(new AppModule(this))
                    .build();
            appComponent.inject(this);
        }
    
        public LockAppComponent getAppComponent() {
    
            return appComponent;
        }
    }
    

    Activity

    public class MainActivity extends AppCompatActivity {
    
        // I get it from ActivityModule
        @Inject
        ContextHelper contextHelper;
    
        // I get it from AppModule
        @Inject
        PrefsHelper prefsHelper;
    
        ActivityComponent component;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
            setupInjection();
        }
    
        protected void setupInjection() {
    
            MyApp application = (MyApp) getApplication();
            component = DaggerActivityComponent.builder()
                    .appComponent(application.getAppComponent())
                    .activityModule(new ActivityModule(this))
                    .build();
            component.inject(this);
    
            // I was also doing the following snippet
            // but it's not the correct way since the ActivityComponent depends
            // on AppComponent and therefore ActivityComponent is the only 
            // component that I should inject() with and I'll still get classes
            // that are provided by the AppComponent/AppModule
    
            // application.getAppComponent().inject(this); // this is unneccessary
        }
    
        public ContextHelper getContextHelper() {
    
            return contextHelper;
        }
    }
    

    I don't know if it directly resolves your issue but it should at least shed some light on how to use Dagger properly.

    Hope it helps.

提交回复
热议问题