android - Koin 未找到类的定义,但已声明
问题描述
我试图使用 Koin 作为我的 DI 来实现权限注入,但是当我执行需要 PermissionRepository 的 ViewModel 时,我一直收到错误。
找不到类的定义:'ni.com.repository.PermissionRepositoryImplement'。检查你的定义!
目前的项目结构是这样的。
基础应用
class BaseApplication : Application() {
companion object{
lateinit var context: BaseApplication
val allAppModules = listOf(coilModule, permissionsModule, blurModule, remoteDataSourceModule, preferencesModule, databaseModule, viewModelModule)
}
override fun onCreate() {
super.onCreate()
context = this
startKoin {
androidLogger()
androidContext(this@BaseApplication)
modules(allAppModules)
}
if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
}
}
PermissionModule但是我需要一个 Activity 来显示权限请求。在 Jetpack Navigation 之后,我使用 MainActivity 作为 Base 并注入到存储库中
val permissionsModule = module {
scope<MainActivity> {
scoped {
PermissionRepositoryImplement(get<MainActivity>())
}
}
}
视图模型模块
val viewModelModule = module {
viewModel { PermissionViewModel(get()) }
}
然后是 PermissionRepositoryImplement
class PermissionRepositoryImplement(private val activity: Activity){
companion object{
private val map = Permission.values().associateBy(Permission::permissionValue)
operator fun get(value: String) = (map[value] ?: error("NOT FOUND"))
}
enum class Key {
granted, denied, forbidden
}
enum class Permission(val permissionValue: String) {
WRITE_EXTERNAL_STORAGE(Manifest.permission.WRITE_EXTERNAL_STORAGE), READ_EXTERNAL_STORAGE(Manifest.permission.READ_EXTERNAL_STORAGE), CAMERA(Manifest.permission.CAMERA), INTERNET(Manifest.permission.INTERNET), INTERNET_STATE(Manifest.permission.ACCESS_WIFI_STATE), NETWORK_STATE(Manifest.permission.ACCESS_NETWORK_STATE),
}
private var result = HashMap<String, String>()
fun requestPermission(permissionName: String): HashMap<String, String> {
activity.let {
it.askPermissions(get(permissionName).permissionValue) {
onGranted {
result[permissionName] = Key.granted.name
}
onDenied {
result[permissionName] = Key.denied.name
}
onShowRationale { request ->
Snackbar.make(it.findViewById(R.id.container), String.format(it.getString(R.string.permissionRequested), Permission.values().filter { p -> p.permissionValue == permissionName }[0]), Snackbar.LENGTH_INDEFINITE)
.setAction("Retry") { request.retry() }
.show()
}
onNeverAskAgain {
result[permissionName] = Key.forbidden.name
}
}
}
return result
}
}
最后是 PermissionViewModel
class PermissionViewModel (private val permissionImplement: PermissionRepositoryImplement): ViewModel() {
private val _uiState = MutableLiveData<CredentialsDataState>()
val uiState: LiveData<CredentialsDataState> get() = _uiState
fun requestPermission(){
viewModelScope.launch {
runCatching {
emitUiState(showProgress = true)
permissionImplement.requestPermission(PermissionRepositoryImplement.Permission.CAMERA.permissionValue)
}.onSuccess {
emitUiState(result = Event(it))
}.onFailure {
emitUiState(error = Event(R.string.error))
}
}
}
private fun emitUiState(showProgress: Boolean = false, result: Event<HashMap<String, String>>? = null, error: Event<Int>? = null){
val dataState = CredentialsDataState(showProgress, result, error)
_uiState.value = dataState
}
data class CredentialsDataState(val showProgress: Boolean, val result: Event<HashMap<String, String>>?, val error: Event<Int>?)
}
在本节之前,一切都应该按照 koin 的需要进行。但我总是收到我的 PermissionRepositoryImplement 没有定义的错误......
解决方案
val permissionsModule = module {
scope<MainActivity> {
scoped {
PermissionRepositoryImplement(get<MainActivity>())
}
}
}
您还没有提供 MainActivity 实例来 koin。那就是你得到错误。
根据我的理解,我们不应该尝试创建 android 组件{活动、广播接收器、服务、内容提供者},我建议使用片段扩展 PermissionRepositoryImplement。
推荐阅读
- python - 无法在 Google colab 中加载 spaCy 模型
- git - 将远程(主)分支重新定位到特定提交
- r - Ifelse 以多列中的相同字符串为条件
- hibernate - 如何从休眠中调用具有自定义数据库类型作为参数的存储过程?
- javascript - 如何在数据表中从 '2021-01-09T00:00:00' LIKE 2021-01-09 转换日期时间格式
- python - 循环遍历 Python 中的变量名称
- wordpress - img_caption_shortcode 的实现没有效果
- c# - Protobuf 无法序列化 system.object
- python - 在 Python Pandas 中,为什么 .describe 和 .describe() 给出不同的结果?
- python - python列表理解与cls