如何在Android/Kotlin应用程序上通过Koin注入来初始化/注入通用视图模型



我正在使用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/

希望它会有所帮助。

最新更新