当我重建项目时,我对dagger 注射有问题.我最近开始学习Dagger 2,我遇到了这个错误,有人能帮我吗?我花了很多时间在上面,你的回答会对我有很大帮助.

[Dagger/MissingBinding] com.example.weatherforecast_rxjava_mvvm_dagger2.data.api.interceptors.LoggingInterceptor cannot be provided without an @Inject constructor or an @Provides-annotated method.
public abstract interface AppComponent {
                ^
  
  Missing binding usage:
      com.example.weatherforecast_rxjava_mvvm_dagger2.data.api.interceptors.LoggingInterceptor is injected at
          com.example.weatherforecast_rxjava_mvvm_dagger2.di.AppModule.provideLoggingInterceptor(loggingInterceptor)
      okhttp3.logging.HttpLoggingInterceptor is injected at
          com.example.weatherforecast_rxjava_mvvm_dagger2.di.AppModule.provideOkHttp(loggingInterceptor)
      okhttp3.OkHttpClient is injected at
          com.example.weatherforecast_rxjava_mvvm_dagger2.di.AppModule.provideRetrofit(okHttp)
      retrofit2.Retrofit.Builder is injected at
          com.example.weatherforecast_rxjava_mvvm_dagger2.di.AppModule.provideApi(builder)
      com.example.weatherforecast_rxjava_mvvm_dagger2.data.api.WeatherApi is injected at
          com.example.weatherforecast_rxjava_mvvm_dagger2.data.repository.WeatherRepositoryImpl(weatherApi, �)
      com.example.weatherforecast_rxjava_mvvm_dagger2.data.repository.WeatherRepositoryImpl is injected at
          com.example.weatherforecast_rxjava_mvvm_dagger2.di.RepositoryModule.bindRepository(repository)
      com.example.weatherforecast_rxjava_mvvm_dagger2.domain.repository.WeatherRepository is injected at
          com.example.weatherforecast_rxjava_mvvm_dagger2.ui.WeatherViewModel(repository, �)
      com.example.weatherforecast_rxjava_mvvm_dagger2.ui.WeatherViewModel is injected at
          com.example.weatherforecast_rxjava_mvvm_dagger2.di.ViewModelModule.bindViewModel(viewModel)
      java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> is injected at
          com.example.weatherforecast_rxjava_mvvm_dagger2.ui.ViewModelFactory(creators)
      com.example.weatherforecast_rxjava_mvvm_dagger2.ui.ViewModelFactory is requested at
          com.example.weatherforecast_rxjava_mvvm_dagger2.di.AppComponent.viewModelFactory()
  The following other entry points also depend on it:
      com.example.weatherforecast_rxjava_mvvm_dagger2.di.AppComponent.inject(com.example.weatherforecast_rxjava_mvvm_dagger2.MainActivity)
[Dagger/MissingBinding] android.app.Application cannot be provided without an @Inject constructor or an @Provides-annotated method.
public abstract interface AppComponent {
                ^
  
  Missing binding usage:
      android.app.Application is injected at
          com.example.weatherforecast_rxjava_mvvm_dagger2.data.location.LocationTrackerImpl(�, application)
      com.example.weatherforecast_rxjava_mvvm_dagger2.data.location.LocationTrackerImpl is injected at
          com.example.weatherforecast_rxjava_mvvm_dagger2.di.LocationModule.bindLocationTracker(locationTracker)
      com.example.weatherforecast_rxjava_mvvm_dagger2.domain.location.LocationTracker is injected at
          com.example.weatherforecast_rxjava_mvvm_dagger2.ui.WeatherViewModel(�, locationTracker)
      com.example.weatherforecast_rxjava_mvvm_dagger2.ui.WeatherViewModel is injected at
          com.example.weatherforecast_rxjava_mvvm_dagger2.di.ViewModelModule.bindViewModel(viewModel)
      java.util.Map<java.lang.Class<? extends androidx.lifecycle.ViewModel>,javax.inject.Provider<androidx.lifecycle.ViewModel>> is injected at
          com.example.weatherforecast_rxjava_mvvm_dagger2.ui.ViewModelFactory(creators)
      com.example.weatherforecast_rxjava_mvvm_dagger2.ui.ViewModelFactory is requested at
          com.example.weatherforecast_rxjava_mvvm_dagger2.di.AppComponent.viewModelFactory()
  It is also requested at:
      com.example.weatherforecast_rxjava_mvvm_dagger2.di.AppModule.provideFusedLocationProviderClient(app)
  The following other entry points also depend on it:
      com.example.weatherforecast_rxjava_mvvm_dagger2.di.AppComponent.inject(com.example.weatherforecast_rxjava_mvvm_dagger2.MainActivity)

以下是我的课程:

AppComponent

@Singleton
@Component(modules = [AppModule::class, LocationModule::class, RepositoryModule::class, ViewModelModule::class])
interface AppComponent {

    fun inject(mainActivity: MainActivity)

    fun viewModelFactory(): ViewModelFactory
}

AppModule

@Module
object AppModule {

    @Provides
    @Singleton
    fun provideApi(builder: Retrofit.Builder): WeatherApi {
        return builder
            .build()
            .create(WeatherApi::class.java)
    }

    @Provides
    @Singleton
    fun provideRetrofit(okHttp: OkHttpClient): Retrofit.Builder {
        return Retrofit.Builder()
            .baseUrl(ApiConstants.API_BASE_URL)
            .client(okHttp)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    }

    @Provides
    @Singleton
    fun provideOkHttp(loggingInterceptor: HttpLoggingInterceptor): OkHttpClient {
        return OkHttpClient.Builder()
            .addInterceptor(loggingInterceptor)
            .build()
    }


    @Provides
    @Singleton
    fun provideLoggingInterceptor(loggingInterceptor: LoggingInterceptor): HttpLoggingInterceptor {
        val httpLoggingInterceptor = HttpLoggingInterceptor(loggingInterceptor)
        httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
        return httpLoggingInterceptor
    }

    @Provides
    @Singleton
    fun provideFusedLocationProviderClient(app: Application): FusedLocationProviderClient {
        return LocationServices.getFusedLocationProviderClient(app)
    }
}

LocationModule

@Module
interface LocationModule {

    @Binds
    @Singleton
    fun bindLocationTracker(locationTracker: LocationTrackerImpl): LocationTracker
}

RepositoryModule

@Module
interface RepositoryModule {

    @Binds
    @Singleton
    fun bindRepository(repository: WeatherRepositoryImpl): WeatherRepository
}

ViewModelKey

@MustBeDocumented
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@MapKey
annotation class ViewModelKey(val value: KClass<out ViewModel>)

ViewModelFactory

@Suppress("UNCHECKED_CAST")
@Singleton
class ViewModelFactory @Inject
constructor(
    private val creators: Map<Class<out ViewModel>,
            @JvmSuppressWildcards Provider<ViewModel>>
) : ViewModelProvider.Factory {

    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        var creator: Provider<out ViewModel>? = creators[modelClass]
        if (creator == null) {
            for ((key, value) in creators) {
                if (modelClass.isAssignableFrom(key)) {
                    creator = value
                    break
                }
            }
        }
        if (creator == null) {
            throw IllegalArgumentException("unknown model class " + modelClass)
        }
        try {
            return creator.get() as T
        } catch (e: Exception) {
            throw RuntimeException(e)
        }

    }
}

WeatherViewModel

class WeatherViewModel @Inject constructor(
    private val repository: WeatherRepository,
    private val locationTracker: LocationTracker
): ViewModel() {

    private val disposables = CompositeDisposable()

    private var _state = MutableStateFlow(WeatherState())
    val state = _state.asStateFlow()

    override fun onCleared() {
        disposables.dispose()
        super.onCleared()
    }

    init {
        locationTracker.getCurrentLocation().subscribe(object : SingleObserver<Location?> {
            override fun onSubscribe(d: Disposable) {
                disposables.add(d)
            }

            override fun onError(e: Throwable) {
                _state.value.weather = State.Error(e.message.orEmpty())
            }

            override fun onSuccess(location: Location) {
                location.let {
                    repository.getWeatherData(it.latitude, it.longitude).subscribe(object : SingleObserver<State<Weather>> {
                        override fun onSubscribe(d: Disposable) {
                            disposables.add(d)
                        }

                        override fun onError(e: Throwable) {
                            _state.value.weather = State.Error(e.message.orEmpty())
                        }

                        override fun onSuccess(weatherState: State<Weather>) {
                            _state.value.weather = weatherState
                        }
                    })
                }
            }
        })
    }
}

WeatherApp

class WeatherApp: Application() {

    lateinit var appComponent: AppComponent

    override fun onCreate() {
        super.onCreate()
        appComponent = DaggerAppComponent.builder().build()
    }
}

val Context.appComponent: AppComponent
    get() = when (this) {
        is WeatherApp -> appComponent
        else -> this.applicationContext.appComponent
    }

MainActivity

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    private lateinit var permissionLauncher: ActivityResultLauncher<Array<String>>

    @Inject
    lateinit var viewModelFactory: ViewModelFactory
    private lateinit var viewModel: WeatherViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        appComponent.inject(this)

        permissionLauncher = registerForActivityResult(
            ActivityResultContracts.RequestMultiplePermissions()
        ) {}
        permissionLauncher.launch(arrayOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION,
        ))
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        viewModel = ViewModelProvider(this, viewModelFactory)[WeatherViewModel::class.java]

        when(val weatherState = viewModel.state.value.weather) {
            is State.Loading -> {
                TODO()
            }
            is State.Success -> {
                TODO()
            }
            is State.Error -> {
                TODO()
            }
        }
    }
}

我试着用谷歌搜索了一下,但都没有用

推荐答案

您的错误表明您正在try 使用一些尚未提供给依赖关系图的对象.

  1. 如果没有@Inject构造函数或@Provides注释的方法,则无法提供com.example.weatherforecast_rxjava_mvvm_dagger2.data.api.interceptors.LoggingInterceptor.

在您的AppModule中,您需要提供LoggingInterceptor的一个实例,以使用它来创建HttpLoggingInterceptor.在ProvideLoggingInterceptor之后添加此函数

@Provides
@Singleton
fun provideLoggingInterceptorImpl(): LoggingInterceptor {
    // return LoggingInterceptor()
}

或者从ProvideLoggingInterceptor函数中删除loggingInterceptor参数.

  1. 在没有@Inject构造函数或@Provides注释的方法的情况下,无法提供android.app.Application.

看起来您的LocationTrackerImpl注入了一个应用程序.将这些行添加到您的AppComponent中,并使用生成器创建它,为图形提供应用程序:

@Component.Builder
interface Builder {

    fun build(): AppComponent

    @BindsInstance
    fun app(app: Application): Builder
}

然后,在创建AppComponent的位置:

val appComponent = DaggerAppComponent.builder().app(this).build()

Android相关问答推荐

使用不同的Google帐户登录

Kotlin DSL:为什么我可以从Play Store获取发布版本的日志(log)?

Android在NavHost中的LazyColumn中编写约束布局:error - replace()在未放置的项目上调用

Modifer.Align()不适用于行/列/框中的文本.未解决的作用域实例错误

FireBase Android ChildEventListener在被规则拒绝时触发(RTDB)

使用Jetpack Compose创建特定于电视的布局

我无法在底部导航栏中正确导航-Android底部导航视图

看不到选项菜单栏

在 kotlin 中动态添加 GridView

Kotlin Multiplatform Mobile targetSdk 已弃用

Composable 不会在单击按钮时重新组合

为片段设置主题

如何关闭可组合对话框?

JetPack Compose - 卡片行中的权重()不起作用

如何处理 com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: For input string: "T1V 4Y8" Kotlin

如何在 Jetpack compose 中将 Canvas 中的文本居中?

如何使用文件提供程序将视频从一个应用程序共享到另一个应用程序?

如何使用 recyclerview 实现这样的布局?

Jetpack Compose Tapjacking:过滤对模糊 UI 的touch

Android:如何获取具有纬度和经度的位置的图像