Dagger 2: 必须设置Module

4

我是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
AppModule需要构造函数吗?@azizbekian - dev_android
1
完全没有。如果您有一个构造函数,那么这个错误将是有意义的。 - azizbekian
如果你在 GitHub 上发布这个项目,我会去看一下。 - azizbekian
1
它正常编译,但在运行时崩溃。请参见截图。如果构建成功,则表示dagger已正确设置,请清理您的项目。 - azizbekian
显示剩余4条评论
4个回答

7
我认为AppModule必须在AppComponent的Builder接口中设置,并且在创建AppComponent时应该提供。 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);

1

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

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

    @ContributesAndroidInjector
    abstract ProductDetailsActivity contributeProductDetailsActivity();
}

我想知道为什么op总是删除那个注释。链接 - azizbekian
哈哈,你说得对 :D 我给你的答案点了个赞,因为它已经是正确的了。 - MatPag
我在问题中忘记提到了。它已经存在于Studio中。 - dev_android

0

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
    }
}

-1
你的Di的整个结构看起来有点奇怪。使用所有这些复杂性的特定原因是什么(考虑到你说你对Dagger还很新,并且所有关于它的教程都没有类似于你的实现)?

2
我正在尝试使用Dagger 2实现Google的新架构组件。实际上,我是按照GoogleSamples提供的GithubBrowserSample进行操作的。 - dev_android

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接