从Kotlin Generic获取泛型类

时间:2018-06-04 09:12:43

标签: android kotlin

我有以下课程签名:

abstract class BaseActivity<E : ViewModel> : AppCompatActivity() {

    protected lateinit var viewModel: E

}

现在我想使用ViewModelProvider以通用方式初始化我的viewModel,所以:

   viewModel = ViewModelProviders.of(this, viewModelFactory)
            .get(MyViewModel::class)

鉴于MyViewModel类将以泛型类型提供,我会说这可能会被抽象到BaseActivity中,所以我不必为扩展它的每个Activity都这样做。

我尝试过:

inline fun <reified E : ViewModel> getViewModelClass() = E::class.java

然后在做的时候:

viewModel = ViewModelProviders.of(this, viewModelFactory)
            .get(getViewModelClass())

我得到Cannot use E as reified type paramter. Use class instead

有解决方法吗?

3 个答案:

答案 0 :(得分:1)

E中的

BaseActivity无法reified,因此您无法将其传递给任何采用reified E的方法。

您最好的选择可能就是接受该类作为构造函数参数。

abstract class BaseActivity<E : ViewModel>(private val modelClass: Class<E>) : AppCompatActivity() {

    protected lateinit var viewModel: E

    ... viewModel = ViewModelProviders.of(this, viewModelFactory)
        .get(modelClass)
}

如果BaseActivity不是抽象的,您可以添加工厂方法:

// outside BaseActivity class itself
fun <reified E : BaseModel> BaseActivity() = BaseActivity(E::class.java)

但是在扩展它时它不会有帮助。

答案 1 :(得分:1)

https://stackoverflow.com/a/52107111/8832537

您应该检查此人的解决方案。他方法的唯一缺点是他使用Reflection API来获取通用参数。我做了很多研究,但没有找到不使用反射的解决方案。如果您找到了,请告诉我。那会更方便。

答案 2 :(得分:0)

你可以这样做:

abstract class BaseActivity<E : ViewModel> : AppCompatActivity() {

protected lateinit var viewModel: E

abstract fun getViewModel():E

override fun onCreate(savedInstanceState: Bundle?){
    super.onCreate(savedInstanceState)
    viewModel = ViewModelProviders.of(this, viewModelFactory)
        .get(getViewModel())
}

}

现在,您可以从BaseActivity扩展任何类,并覆盖返回相应ViewModel类的getViewModel()函数。

希望这有帮助。

修改

尝试一次:

 inline fun <reified E> getViewModelClass(): Class<E> {
    return E::class.java
}

并像这样使用它:

viewModel = ViewModelProviders.of(this, viewModelFactory)
        .get(getViewModelClass())