没有 @Provides-annotated 方法无法提供匕首柄
Dagger hilt Cannot be provided without an @Provides-annotated method
我刚开始使用匕首。所以,我无法解决这个问题。我就是想在这里问一下解决。
这是错误:
C:\Users\msi\Documents\MyAndroidProjects\MovieProjects\app\build\generated\hilt\component_sources\debug\com\example\movieapp\App_HiltComponents.java:128:
error: [Dagger/MissingBinding]
com.example.movieapp.api.MovieAppService cannot be provided without an
@Provides-annotated method. public abstract static class SingletonC
implements App_GeneratedInjector,
^
com.example.movieapp.api.MovieAppService is injected at
com.example.movieapp.repository.MovieRepository(movieAppService)
com.example.movieapp.repository.MovieRepository is injected at
com.example.movieapp.viewmodel.MainViewModel(repository, �)
com.example.movieapp.viewmodel.MainViewModel is injected at
com.example.movieapp.viewmodel.MainViewModel_HiltModules.BindsModule.binds(arg0)
@dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.String,javax.inject.Provider<androidx.lifecycle.ViewModel>>
is requested at
dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint.getHiltViewModelMap()
[com.example.movieapp.App_HiltComponents.SingletonC ?
com.example.movieapp.App_HiltComponents.ActivityRetainedC ?
com.example.movieapp.App_HiltComponents.ViewModelC]
MainViewModel.kt
@HiltViewModel
class MainViewModel@Inject constructor(
private val repository: MovieRepository,
@ApplicationContext private val context: Context
) : ViewModel() {
val movieList = MutableLiveData<Resource<Movie>>()
fun getAllMovies(movieName: String) {
movieList.postValue(Resource.Loading())
viewModelScope.launch {
try {
if (hasInternetConnection(context)) {
val response = repository.getMovies(movieName, "ffe9063f")
movieList.postValue(Resource.Success(response.body()!!))
} else
movieList.postValue(Resource.Error("Internet yok"))
} catch (ex: Exception) {
when (ex) {
is IOException -> movieList.postValue(Resource.Error("Network Failure " + ex.localizedMessage))
else -> movieList.postValue(Resource.Error("Conversion Error"))
}
}
}
}
}
MovieRepository.kt
@Singleton
class MovieRepository @Inject constructor(private val movieAppService: MovieAppService) {
suspend fun getMovies(title: String, aKey: String): Response<Movie> = withContext(
Dispatchers.IO
) {
val movies = movieAppService.getMovies(title = title, aKey = aKey)
movies
}
}
ApiModule.kt
class ApiModule {
@Module
@InstallIn(SingletonComponent::class)
object ApiModule {
@Provides
@Singleton
fun provideLoggingInterceptor(): HttpLoggingInterceptor {
return HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
}
@Provides
@Singleton
fun provideOkHttpClient(logging: HttpLoggingInterceptor): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(logging)
.connectTimeout(15, TimeUnit.SECONDS) // connect timeout
.readTimeout(15, TimeUnit.SECONDS)
.build()
}
@Provides
@Singleton
fun provideRetrofit(client: OkHttpClient): Retrofit {
return Retrofit.Builder()
.baseUrl(ENDPOINT)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build()
}
@Provides
@Singleton
fun provideMovieAppService(retrofit: Retrofit): MovieAppService {
return retrofit.create(MovieAppService::class.java)
}
}
}
MovieAppService.kt
interface MovieAppService {
companion object {
const val ENDPOINT = "http://www.omdbapi.com/"
}
@GET(".")
suspend fun getMovies(@Query("t") title: String,@Query("apikey") aKey: String): Response<Movie>
}
不要用同名 class 包装你的单例对象模块。像这样更改您的模块文件或更改您的 class 名称
@Module
@InstallIn(SingletonComponent::class)
object ApiModule {
@Provides
@Singleton
fun provideLoggingInterceptor(): HttpLoggingInterceptor {
return HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
}
@Provides
@Singleton
fun provideOkHttpClient(logging: HttpLoggingInterceptor): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(logging)
.connectTimeout(15, TimeUnit.SECONDS) // connect timeout
.readTimeout(15, TimeUnit.SECONDS)
.build()
}
@Provides
@Singleton
fun provideRetrofit(client: OkHttpClient): Retrofit {
return Retrofit.Builder()
.baseUrl(ENDPOINT)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build()
}
@Provides
@Singleton
fun provideMovieAppService(retrofit: Retrofit): MovieAppService {
return retrofit.create(MovieAppService::class.java)
}
}
我刚开始使用匕首。所以,我无法解决这个问题。我就是想在这里问一下解决。
这是错误:
C:\Users\msi\Documents\MyAndroidProjects\MovieProjects\app\build\generated\hilt\component_sources\debug\com\example\movieapp\App_HiltComponents.java:128: error: [Dagger/MissingBinding] com.example.movieapp.api.MovieAppService cannot be provided without an @Provides-annotated method. public abstract static class SingletonC implements App_GeneratedInjector, ^ com.example.movieapp.api.MovieAppService is injected at com.example.movieapp.repository.MovieRepository(movieAppService) com.example.movieapp.repository.MovieRepository is injected at com.example.movieapp.viewmodel.MainViewModel(repository, �) com.example.movieapp.viewmodel.MainViewModel is injected at com.example.movieapp.viewmodel.MainViewModel_HiltModules.BindsModule.binds(arg0) @dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.String,javax.inject.Provider<androidx.lifecycle.ViewModel>> is requested at dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint.getHiltViewModelMap() [com.example.movieapp.App_HiltComponents.SingletonC ? com.example.movieapp.App_HiltComponents.ActivityRetainedC ? com.example.movieapp.App_HiltComponents.ViewModelC]
MainViewModel.kt
@HiltViewModel
class MainViewModel@Inject constructor(
private val repository: MovieRepository,
@ApplicationContext private val context: Context
) : ViewModel() {
val movieList = MutableLiveData<Resource<Movie>>()
fun getAllMovies(movieName: String) {
movieList.postValue(Resource.Loading())
viewModelScope.launch {
try {
if (hasInternetConnection(context)) {
val response = repository.getMovies(movieName, "ffe9063f")
movieList.postValue(Resource.Success(response.body()!!))
} else
movieList.postValue(Resource.Error("Internet yok"))
} catch (ex: Exception) {
when (ex) {
is IOException -> movieList.postValue(Resource.Error("Network Failure " + ex.localizedMessage))
else -> movieList.postValue(Resource.Error("Conversion Error"))
}
}
}
}
}
MovieRepository.kt
@Singleton
class MovieRepository @Inject constructor(private val movieAppService: MovieAppService) {
suspend fun getMovies(title: String, aKey: String): Response<Movie> = withContext(
Dispatchers.IO
) {
val movies = movieAppService.getMovies(title = title, aKey = aKey)
movies
}
}
ApiModule.kt
class ApiModule {
@Module
@InstallIn(SingletonComponent::class)
object ApiModule {
@Provides
@Singleton
fun provideLoggingInterceptor(): HttpLoggingInterceptor {
return HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
}
@Provides
@Singleton
fun provideOkHttpClient(logging: HttpLoggingInterceptor): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(logging)
.connectTimeout(15, TimeUnit.SECONDS) // connect timeout
.readTimeout(15, TimeUnit.SECONDS)
.build()
}
@Provides
@Singleton
fun provideRetrofit(client: OkHttpClient): Retrofit {
return Retrofit.Builder()
.baseUrl(ENDPOINT)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build()
}
@Provides
@Singleton
fun provideMovieAppService(retrofit: Retrofit): MovieAppService {
return retrofit.create(MovieAppService::class.java)
}
}
}
MovieAppService.kt
interface MovieAppService {
companion object {
const val ENDPOINT = "http://www.omdbapi.com/"
}
@GET(".")
suspend fun getMovies(@Query("t") title: String,@Query("apikey") aKey: String): Response<Movie>
}
不要用同名 class 包装你的单例对象模块。像这样更改您的模块文件或更改您的 class 名称
@Module
@InstallIn(SingletonComponent::class)
object ApiModule {
@Provides
@Singleton
fun provideLoggingInterceptor(): HttpLoggingInterceptor {
return HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
}
@Provides
@Singleton
fun provideOkHttpClient(logging: HttpLoggingInterceptor): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(logging)
.connectTimeout(15, TimeUnit.SECONDS) // connect timeout
.readTimeout(15, TimeUnit.SECONDS)
.build()
}
@Provides
@Singleton
fun provideRetrofit(client: OkHttpClient): Retrofit {
return Retrofit.Builder()
.baseUrl(ENDPOINT)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build()
}
@Provides
@Singleton
fun provideMovieAppService(retrofit: Retrofit): MovieAppService {
return retrofit.create(MovieAppService::class.java)
}
}