创建泛型ViewModel时报错(Kotlin get type of generic class without instance)

错误示例

话不多说,直接上代码

abstract class BaseAct<T:BaseViewModel> :AppCompatActivity(){
    protected lateinit var mActivity:AppCompatActivity
    protected lateinit var mContext: Context
    protected lateinit var mViewModel: T

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(getLayoutViewId())
        mActivity  = this
        mContext = this
       
        mViewModel = ViewModelProvider(this,
            ViewModelProvider.AndroidViewModelFactory.getInstance(application)).get(T::class.java)
        onCreated(savedInstanceState)
    }
    abstract fun getLayoutViewId():Int
    abstract fun onCreated(savedInstanceState: Bundle?)
}

以上代码中,我想去创建一个泛型ViewModel的实例,然后报错:
Kotlin get type of generic class without instance

这样中时不行的因为,具体的实例kotlin不能知道是什么对象,这里需要利用反射。
参考了代码:

 /**
     * 创建 ViewModel
     */
    @Suppress("UNCHECKED_CAST")
    private fun createViewModel() {
        //这儿为啥要用反射 我的理解是反射取出viewModel超类 判断是否是BaseViewModel,ParameterizedType这个是参数化泛型
        val type = javaClass.genericSuperclass
        if (type is ParameterizedType) {
            val tp = type.actualTypeArguments[0]
            val tClass = tp as? Class<VM> ?: BaseViewModel::class.java
             //你问我为啥要用工厂,我刚开始也不知道,后来在csdn上看别人的学习资料的时候才知道              ViewModelProviders.of new对象创建,已经被弃用了
            viewModel = ViewModelProvider(this, ViewModelFactory()).get(tClass) as VM
        }
    }

Kotlin的反思:未知的类型参数 获取方式

“androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0”

注意这里创建viewmodel的方式,ViewModelProvider.of方式在2.2.0已舍弃

最后看一下我的项目damo

代码实例

创建BaseViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch

open class BaseViewModel : ViewModel(){
    var mutableLiveData:MutableLiveData<String> = MutableLiveData()

    fun launch(mutableLiveData:MutableLiveData<String>,block:()->Unit){
        viewModelScope.launch {
            block()
            mutableLiveData.value = "wpf"
        }
    }
}
创建BaseActivity
import android.content.Context
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import java.lang.reflect.ParameterizedType

abstract class BaseAct<T:BaseViewModel> :AppCompatActivity(){
    protected lateinit var mActivity:AppCompatActivity
    protected lateinit var mContext: Context
    protected lateinit var mViewModel: T

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(getLayoutViewId())
        mActivity  = this
        mContext = this
        /*利用反射获取类实例*/
        val persistentClass = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<T>
        mViewModel = ViewModelProvider(this,
            ViewModelProvider.AndroidViewModelFactory.getInstance(application)).get(persistentClass)
        onCreated(savedInstanceState)
    }
    abstract fun getLayoutViewId():Int
    abstract fun onCreated(savedInstanceState: Bundle?)
}
具体ViewModel实例

import android.util.Log
import com.wpf.common_module.BaseViewModel

class TestViewModel :BaseViewModel() {

    fun doThing(){
        Log.e("wpf","TestViewModel")
    }
}
使用
import android.os.Bundle
import android.util.Log
import android.widget.TextView
import androidx.lifecycle.Observer
import com.wpf.common_module.BaseAct
import com.wpf.studywork.R

class TestAct : BaseAct<TestViewModel>() {

    override fun getLayoutViewId(): Int= R.layout.activity_test

    override fun onCreated(savedInstanceState: Bundle?) {
        var testViewModel:TextView = findViewById(R.id.textView)
        testViewModel.setOnClickListener {
            mViewModel.launch(mViewModel.mutableLiveData){
                Log.e("wpf","123")
            }
            mViewModel.doThing()
        }
        mViewModel.mutableLiveData.observe(this, Observer{
            Log.e("wpf","::::$it")
        })
    }
}

这里使用的好处是,任何你继承BaseViewModel的类,都可以使用其方法,也可以自己定义方法,快捷方便。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

feipengwang6666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值