【问题标题】:Dagger 2 : Module must be setDagger 2:必须设置模块
【发布时间】:2018-01-03 03:05:09
【问题描述】:

我是 Dagger 2 的新手。我已经尝试过设置。这是我的ActivityModule

@Module
public abstract class ActivityModule {
    @ContributesAndroidInjector
    abstract ProductListActivity contributeProductListActivity();

    @ContributesAndroidInjector
    abstract ProductDetailsActivity contributeProductDetailsActivity();
}

我的AppModule

@Module
class AppModule {

@Provides
    @Singleton
    RedMartProductService provideRedMartProductService() {
        ........
    }
    ........
    .......
}

我的AppComponent

@Singleton
@Component(modules = {AndroidInjectionModule.class, ActivityModule.class, AppModule.class})
public interface AppComponent {
    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder application(Application application);

        AppComponent build();
    }

    void inject(MartApplication martApp);
}

我的应用程序

public class MartApplication extends Application implements HasActivityInjector {

    @Inject
    DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;

    @Override
    public void onCreate() {
        super.onCreate();
        AppInjector.init(this);
    }

    @Override
    public DispatchingAndroidInjector<Activity> activityInjector() {
        return dispatchingAndroidInjector;
    }
}

AppInjector中:

public class AppInjector {
private AppInjector() {
}

public static void init(MartApplication application) {
    DaggerAppComponent.builder().application(application)
            .build().inject(application);
    application
            .registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
                @Override
                public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                    handleActivity(activity);
                }

                ............
            });
}

private static void handleActivity(Activity activity) {
    if (activity instanceof Injectable) { //HasSupportFragmentInjector) {
        AndroidInjection.inject(activity);
    }
    if (activity instanceof FragmentActivity) {
        ((FragmentActivity) activity).getSupportFragmentManager()
                .registerFragmentLifecycleCallbacks(
                        new FragmentManager.FragmentLifecycleCallbacks() {
                            @Override
                            public void onFragmentCreated(FragmentManager fm, Fragment f,
                                                          Bundle savedInstanceState) {
                                if (f instanceof Injectable) {
                                    AndroidSupportInjection.inject(f);
                                }
                            }
                        }, true);
    }
}

}

在注入时抛出异常:

java.lang.RuntimeException: Unable to create application com.kaushik.myredmart.MartApplication: java.lang.IllegalStateException: com.kaushik.myredmart.di.AppModule                              must be set at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4710)
                                                 at android.app.ActivityThread.-wrap1(ActivityThread.java)
                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405)
                                                 at android.os.Handler.dispatchMessage(Handler.java:102)
                                                 at android.os.Looper.loop(Looper.java:148)
                                                 at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                              Caused by: java.lang.IllegalStateException: com.mymart.di.AppModule must be set
                                                 at com.kaushik.myredmart.di.DaggerAppComponent$Builder.build(DaggerAppComponent.java:180)
                                                 at com.kaushik.myredmart.di.AppInjector.init(AppInjector.java:30)
                                                 at com.kaushik.myredmart.MartApplication.onCreate(MartApplication.java:28)
                                                 at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1013)
                                                 at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4707)
                                                 at android.app.ActivityThread.-wrap1(ActivityThread.java) 
                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405) 
                                                 at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                 at android.os.Looper.loop(Looper.java:148) 
                                                 at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                 at java.lang.reflect.Method.invoke(Native Method)

谁能帮我弄清楚我的设置中的实际问题在哪里?

【问题讨论】:

  • AppModule 有构造函数吗?
  • 没有构造函数@azizbekian
  • 构造函数是否为 rqd。应用模块? @azizbekian
  • 完全没有。如果你有一个构造函数 - 这个错误将是有意义的。
  • 正常编译,运行时崩溃。 See screenshot。如果构建成功,则意味着 dagger 设置正确,请清理您的项目。

标签: android dagger-2 dagger


【解决方案1】:

我认为AppModule 必须在 AppComponent 的 Builder 界面中设置,并且应该在创建 AppComponent 时提供。

应用组件:

@Singleton
@Component(modules = {AndroidInjectionModule.class, ActivityModule.class, AppModule.class})
public interface AppComponent {
    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder application(Application application);

        Builder appModule(AppModule appModule); // add this

        AppComponent build();
    }

    void inject(MartApplication martApp);
}

AppInjector:

init 方法内部:

DaggerAppComponent.builder()
.application(application)
.appModule(new AppModule()) // add this
.build()
.inject(application);

【讨论】:

    【解决方案2】:

    您需要将@ContributesAndroidInjector 添加到ActivityModule 中的抽象方法中

    @Module
    public abstract class ActivityModule {
        @ContributesAndroidInjector
        abstract ProductListActivity contributeProductListActivity();
    
        @ContributesAndroidInjector
        abstract ProductDetailsActivity contributeProductDetailsActivity();
    }
    

    【讨论】:

    • 我想知道为什么 op always removes 那个注释?
    • 大声笑,你是对的 :D i +1'd 你的答案已经正确了
    • 我忘了提问题。它已经在 Studio 中了。
    【解决方案3】:

    Kotlin 版本。 AppComponent.kt:

    import com.domain.app_name.core.domain.App
    import com.domain.app_name.splash.di.SplashModule
    import com.domain.app_name.splash.presentation.BusinessLoginBottomSheet
    import dagger.Component
    import dagger.android.AndroidInjectionModule
    import javax.inject.Singleton
    import dagger.BindsInstance
    
    @Singleton
    @Component(modules = [
        AndroidInjectionModule::class,
        AppModule::class,
        SplashModule::class
    ])
    interface AppComponent {
    
        @Component.Builder
        interface Builder {
            @BindsInstance
            fun app(app : App) : Builder
            fun appModule(appModule : AppModule) : Builder
            fun build() : AppComponent
        }
    
        fun inject(app : App)
        fun inject(businessLoginBottomSheet : BusinessLoginBottomSheet)
        fun inject(appModule : AppModule)
    }
    

    App.kt:

    import android.app.Application
    import com.domain.app_name.core.di.AppModule
    import com.domain.app_name.core.di.DaggerAppComponent
    import dagger.android.AndroidInjector
    import dagger.android.DispatchingAndroidInjector
    import dagger.android.HasAndroidInjector
    import javax.inject.Inject
    
    class App : Application(), HasAndroidInjector {
    
        @Inject
        lateinit var injector: DispatchingAndroidInjector<Any>
    
        override fun onCreate() {
            super.onCreate()
            DaggerAppComponent.builder()
                .app(this)
                .appModule(AppModule(this))
                .build()
                .inject(this)
        }
    
        override fun androidInjector() : AndroidInjector<Any> {
            return injector
        }
    }
    

    【讨论】:

      【解决方案4】:

      你的 Di 的整个结构看起来有点奇怪。使用所有这些复杂性的任何特定原因(记住你说你是 Dagger 的新手,并且它的所有教程都没有任何接近你的实现的东西)?

      【讨论】:

      • 我正在尝试使用 Dagger 2 实现 Google 新架构组件。我实际上是在关注 GoogleSamples 提供的 GithubBrowserSample
      猜你喜欢
      • 1970-01-01
      • 2018-10-02
      • 1970-01-01
      • 2017-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-20
      • 2015-11-01
      相关资源
      最近更新 更多