Java 如果没有@Inject构造函数或@Provides注释方法-Dagger 2,则无法提供

Java 如果没有@Inject构造函数或@Provides注释方法-Dagger 2,则无法提供,java,android,dagger-2,dagger,Java,Android,Dagger 2,Dagger,我正在使用匕首2,但得到了这个奇怪的错误,到目前为止似乎没有什么不好,但很明显,有什么东西丢失了。任何帮助都将不胜感激 Error:(16, 8) error: [dagger.android.AndroidInjector.inject(T)] com.example.user.viewmodel.TripViewModel cannot be provided without an @Inject constructor or from an @Provides-annotated meth

我正在使用匕首2,但得到了这个奇怪的错误,到目前为止似乎没有什么不好,但很明显,有什么东西丢失了。任何帮助都将不胜感激

Error:(16, 8) error: [dagger.android.AndroidInjector.inject(T)] com.example.user.viewmodel.TripViewModel cannot be provided without an @Inject constructor or from an @Provides-annotated method. This type supports members injection but cannot be implicitly provided.
com.example.user.viewmodel.TripViewModel is injected at
com.example.user.di.ViewModelModule.bindTripViewModel(tripViewModel)
java.util.Map<java.lang.Class<? extends android.arch.lifecycle.ViewModel>,javax.inject.Provider<android.arch.lifecycle.ViewModel>> is injected at
com.example.user.di.TripViewModelFactory.<init>(creators)
com.example.user.di.TripViewModelFactory is injected at
com.example.user.di.ViewModelModule.bindViewModelFactory(factory)
android.arch.lifecycle.ViewModelProvider.Factory is injected at
com.example.user.fragment.HomeFragment.viewModelFactory
com.example.user.fragment.HomeFragment is injected at
dagger.android.AndroidInjector.inject(arg0)
ViewModelModule.java

@Module(includes = ViewModelModule.class)
class AppModule {
    @Singleton
    @Provides
    MyRoomDatabase providesRoomDatabase(Application application) {
        return Room.databaseBuilder(application,
                MyRoomDatabase.class, "name_db").build();
    }

    @Singleton
    @Provides
    TripRepository provideTripRepository(TripDao tripDao){
        return new TripRepository(tripDao);
    }

    @Singleton
    @Provides
    TripDao provideTripDao(MyRoomDatabase myRoomDatabase){
        return myRoomDatabase.getTripDao();
    }

}
@Module
public abstract class ViewModelModule {
    @Binds
    @IntoMap
    @ViewModelKey(TripViewModel.class)
    abstract ViewModel bindTripViewModel(TripViewModel tripViewModel);

    @Binds
    abstract ViewModelProvider.Factory bindViewModelFactory(TripViewModelFactory factory);
}
@Module
public abstract class MainActivityModule {
    @ContributesAndroidInjector(modules = FragmentBuildersModule.class)
    abstract MainActivity contributeMainActivity();
}
@Module
public abstract class FragmentBuildersModule {
    @ContributesAndroidInjector
    abstract HomeFragment contributeRepoFragment();
}
MainActivityModule.java

@Module(includes = ViewModelModule.class)
class AppModule {
    @Singleton
    @Provides
    MyRoomDatabase providesRoomDatabase(Application application) {
        return Room.databaseBuilder(application,
                MyRoomDatabase.class, "name_db").build();
    }

    @Singleton
    @Provides
    TripRepository provideTripRepository(TripDao tripDao){
        return new TripRepository(tripDao);
    }

    @Singleton
    @Provides
    TripDao provideTripDao(MyRoomDatabase myRoomDatabase){
        return myRoomDatabase.getTripDao();
    }

}
@Module
public abstract class ViewModelModule {
    @Binds
    @IntoMap
    @ViewModelKey(TripViewModel.class)
    abstract ViewModel bindTripViewModel(TripViewModel tripViewModel);

    @Binds
    abstract ViewModelProvider.Factory bindViewModelFactory(TripViewModelFactory factory);
}
@Module
public abstract class MainActivityModule {
    @ContributesAndroidInjector(modules = FragmentBuildersModule.class)
    abstract MainActivity contributeMainActivity();
}
@Module
public abstract class FragmentBuildersModule {
    @ContributesAndroidInjector
    abstract HomeFragment contributeRepoFragment();
}
FragmentBuilderModule.java

@Module(includes = ViewModelModule.class)
class AppModule {
    @Singleton
    @Provides
    MyRoomDatabase providesRoomDatabase(Application application) {
        return Room.databaseBuilder(application,
                MyRoomDatabase.class, "name_db").build();
    }

    @Singleton
    @Provides
    TripRepository provideTripRepository(TripDao tripDao){
        return new TripRepository(tripDao);
    }

    @Singleton
    @Provides
    TripDao provideTripDao(MyRoomDatabase myRoomDatabase){
        return myRoomDatabase.getTripDao();
    }

}
@Module
public abstract class ViewModelModule {
    @Binds
    @IntoMap
    @ViewModelKey(TripViewModel.class)
    abstract ViewModel bindTripViewModel(TripViewModel tripViewModel);

    @Binds
    abstract ViewModelProvider.Factory bindViewModelFactory(TripViewModelFactory factory);
}
@Module
public abstract class MainActivityModule {
    @ContributesAndroidInjector(modules = FragmentBuildersModule.class)
    abstract MainActivity contributeMainActivity();
}
@Module
public abstract class FragmentBuildersModule {
    @ContributesAndroidInjector
    abstract HomeFragment contributeRepoFragment();
}
AppComponent.java

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

        AppComponent build();
    }
    void inject(FuelApp fuelApp);
}
AppInjector.java

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

                    @Override
                    public void onActivityStarted(Activity activity) {

                    }

                    @Override
                    public void onActivityResumed(Activity activity) {

                    }

                    @Override
                    public void onActivityPaused(Activity activity) {

                    }

                    @Override
                    public void onActivityStopped(Activity activity) {

                    }

                    @Override
                    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

                    }

                    @Override
                    public void onActivityDestroyed(Activity activity) {

                    }
                });
    }

    private static void handleActivity(Activity activity) {
        if (activity instanceof 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);
        }
    }
}
ViewModelKey.java

@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@MapKey
@interface ViewModelKey {
    Class<? extends ViewModel> value();
}

我已经解决了这个问题。错误是由错误的ViewModel构造函数声明引起的。在我的代码中,我使用了一个工厂类(TripViewModelFactory),以便将我的TripViewModel类与具有非零参数的构造函数一起使用,这些参数由Dagger注入。我的TripViewModel类构造函数声明有问题,工厂类打算调用的构造函数没有被调用。因此,没有创建ViewModel实例,这导致了问题中给出的错误


另外,如果您使用与我在问题中共享的相同的代码结构,那么从工厂类创建viewmodel实例的片段类必须实现可注入接口。这一个在我的代码中创建了另一个bug,很高兴与大家分享。

您如何/在哪里提供
TripViewModel
?您既没有显示(带注释的)构造函数,也没有显示提供它的模块。请参见此处:@DavidMedenjak请参见我的editTripViewModel在您的图形中不存在:您可以注入TripViewModelFactory,但Dagger不知道如何从其中一个到您试图在图形中绑定的TripViewModel。此外,您为TripViewModelFactory编写的代码似乎使用了多重绑定创建的映射,因此将任何种类的TripViewModelFactory绑定到该图中都会产生循环引用。你想在这里干什么?当图形中的对象需要TripViewModel时,您是希望它们注入TripViewModelFactory还是您的地图?或者他们只想要一个TripViewModel子类?实际上,我只希望TripViewModel作为图形中的一个对象可用,因为我的TripViewModel构造函数有参数,所以我必须包含一个TripViewModelFactory。你的解释很有道理,但我还是想不出解决办法。