我正在尝试在我的 Kotlin 应用程序中创建一个 ViewModel,但出现以下错误:java.lang.RuntimeException:无法创建类 com.ri.movieto.presentation.home.HomeViewModel 的实例。另外,我正在使用 Hilt。
这是我的 HomeFragment 的代码:
@AndroidEntryPoint
class HomeFragment : Fragment() {
private var _binding: FragmentHomeBinding? = null
private val homeViewModel: HomeViewModel by viewModels()
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentHomeBinding.inflate(inflater, container, false)
contentLayout = binding.contentLayout
dataLoading = binding.dataLoading
observeLiveData()
return binding.root
}
private fun subscribeToObservables() {
lifecycleScope.launchWhenStarted {
homeViewModel.state.collectLatest {
Log.e("++++", it.response?.page.toString())
}
}
}
}
这是我的 HomeViewModel 的代码:
@HiltViewModel
class HomeViewModel @Inject constructor(
private val getTrendingMoviesUseCase: GetTrendingMoviesUseCase
) : ViewModel() {
private val _state = MutableStateFlow(TrendingMoviesState())
val state = _state.asStateFlow()
init {
getTrendingMovies()
}
private fun getTrendingMovies() {
getTrendingMoviesUseCase().onEach { result ->
when (result) {
is Resource.Success -> {
_state.value = TrendingMoviesState(response = result.data)
}
is Resource.Error -> {
_state.value =
TrendingMoviesState(error = result.message ?: "An unexpected error occurred")
}
is Resource.Loading -> {
_state.value = TrendingMoviesState(isLoading = true)
}
}
}
}
}
GetTrendingMoviesUseCase.kt:
class GetTrendingMoviesUseCase @Inject constructor(
private val repository: MovieRepository,
private val movieResponseDtoToDomain: MovieResponseDtoToDomain
) {
operator fun invoke(): Flow<Resource<MovieResponse>> = flow {
try {
emit(Resource.Loading())
val movieResponseDto = repository.getTrendingMovies()
val movieResponse = movieResponseDtoToDomain.mapFrom(movieResponseDto)
emit(Resource.Success(movieResponse))
} catch (e: HttpException) {
emit(Resource.Error(e.localizedMessage ?: "Beklenmeyen bir hata oluştu"))
} catch (e: IOException) {
emit(Resource.Error("Lütfen internet bağlantınızı kontrol edin"))
}
}
}
MovieResponseDtoToDomain.kt:
@Singleton
class MovieResponseDtoToDomain @Inject constructor(private val itemDecider: MovieItemDecider) :
Mapper<MovieResponseDto, MovieResponse> {
override fun mapFrom(input: MovieResponseDto): MovieResponse {
return MovieResponse(
page = input.page,
movies = input.results.map { movie ->
MovieResponse.Movie(
release_year = itemDecider.provideReleaseYear(movie.release_date),
poster_path = itemDecider.providePosterPath(movie.poster_path),
backdrop_path = itemDecider.provideBackdropPath(movie.backdrop_path),
vote_average = itemDecider.provideRoundedAverage(movie.vote_average),
title = movie.title,
id = movie.id,
video = movie.video,
release_date = movie.release_date,
overview = movie.overview,
genre_ids = movie.genre_ids
)
},
total_pages = input.total_pages,
total_results = input.total_results
)
}
}