如何在 Android/Kotlin App 上通过 Koin 注入在 BaseActivity 中初始化/注入通用 ViewModel
Posted
技术标签:
【中文标题】如何在 Android/Kotlin App 上通过 Koin 注入在 BaseActivity 中初始化/注入通用 ViewModel【英文标题】:How to initialize/inject generic ViewModel in BaseActivity by Koin injection on Android/Kotlin App 【发布时间】:2018-07-24 10:57:21 【问题描述】:我正在使用 Kotlin 和 android 架构组件(ViewModel、LiveData)构建新的 Android 应用程序的架构,并且我还使用 Koin 作为我的依赖注入提供程序。
问题是我无法通过 koin 注入在 BaseActivity 中以通用方式初始化 ViewModel。当前代码如下所示:
abstract class BaseActivity<ViewModelType : ViewModel> : AppCompatActivity()
// This does not compile because of the generic type
private val viewModel by lazy
// Koin implementation to inject ViewModel
getViewModel<ViewModelType>()
@CallSuper
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
Fabric.with(this, Crashlytics())
/**
* Method needed for Calligraphy library configuration
*/
@CallSuper
override fun attachBaseContext(newBase: Context)
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase))
我想知道是否有办法在 Kotlin 中做到这一点,因为我很确定我可以轻松地在 Java 中做到这一点。 谢谢。
【问题讨论】:
【参考方案1】:koin 团队在0.9.0-alpha-11
版本中提供了解决方案,最终代码如下所示:
open class BaseActivity<out ViewModelType : BaseViewModel>(clazz: KClass<ViewModelType>) :
AppCompatActivity()
val viewModel: ViewModelType by viewModel(clazz)
fun snackbar(message: String?)
message?.let longSnackbar(find(android.R.id.content), it)
fun toast(message: String?)
message?.let longToast(message)
【讨论】:
用val viewModel: ViewModelType by viewModelByClass(clazz)
替换val viewModel: ViewModelType by viewModel(clazz)
有没有办法防止必须通过 Class 和 Generic?扩展时,您必须这样做: class Other:BaseActivity这是不将Class and Generic
传递给基本实现的示例
在您的基础片段/活动中:
abstract class BaseFragment<T : BaseViewModel> : Fragment()
...
@Suppress("UNCHECKED_CAST")
private val clazz: KClass<T> = ((this.javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<T>).kotlin
protected val viewModel: T by viewModel(clazz = clazz)
...
它看起来很难看,但它确实有效。
【讨论】:
【参考方案3】:您可以为您的 ViewModel 使用委托版本声明,并避免直接使用惰性表达式。试试这个:
abstract class BaseActivity<T : ViewModel> : AppCompatActivity()
val model by viewModel<T>()
这会让你变得懒惰
getViewModel<T>()
关注快速参考:https://insert-koin.io/docs/1.0/getting-started/android-viewmodel/
希望它会有所帮助。
【讨论】:
这个不行,还是要reified type parameter 这不起作用,因为它是具体的类型参数,你必须使用类本身以上是关于如何在 Android/Kotlin App 上通过 Koin 注入在 BaseActivity 中初始化/注入通用 ViewModel的主要内容,如果未能解决你的问题,请参考以下文章
Android Kotlin:null 不能转换为非 null 类型 com.android.app.ui.category.CategoryAdapter.ViewHolder 想要在 recycl
android:kotlin语言使用greendao3,跨平台app开发框架
Android kotlin 组件间通讯 - LiveEventBus 及测试(更新中)
如何在 Android Kotlin 中创建 BottomSheet