我正在使用Kotlin和Android体系结构组件(ViewModel,Livedata(构建新的Android应用程序的体系结构,而且我还将Koin用作我的依赖性注入提供商。
问题是,我无法通过Koin注入以通用的方式初始化视图模型。当前的代码看起来像这样:
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中做。谢谢。
该解决方案是由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) }
}
}
这是不传递 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)
...
}
看起来很丑,但起作用。
您可以为您的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/
希望它会有所帮助。