Kotlin安卓开发Type Mismatch required List found LiveData报错问询
类型不匹配报错原因及修复方案
报错根本原因
- 赋值两侧类型不匹配:
- 赋值左侧
_auth.value的要求类型是List<AuthModel>?:_auth是MutableLiveData<List<AuthModel>>类型,它的value属性存储的是LiveData包裹的实际数据,也就是泛型指定的List<AuthModel>类型,可空。 - 赋值右侧
authRepository.login(username, password)的实际返回类型是LiveData<List<AuthModel>>:你在AuthRepository中定义的login方法返回的是成员变量auth,这个auth本身是Room返回的LiveData包装类,不是内部包裹的List数据。
你直接把LiveData包装类对象赋值给需要实际List数据的属性,就会触发对应的类型不匹配报错。
- 赋值左侧
修复方案
有两种常用的修复方式,优先选择第一种符合Android响应式编程规范的方案:
方案1:直接观察Repository的响应式LiveData
Room的DAO返回的LiveData本身支持自动观察数据库变化,你不需要手动把数据同步到ViewModel的LiveData中,只需要调用login触发网络请求+数据库写入即可,数据变化会自动通知到View层:
// LoginViewModel 调整代码 class LoginViewModel(application: Application) : AndroidViewModel(application) { private val authRepository = AuthRepository(database) // 直接持有Repository的auth,不需要额外定义中间变量_auth val auth: LiveData<List<AuthModel>> get() = authRepository.auth private fun apiLogin(username: String, password: String) { viewModelScope.launch { try{ // login仅负责触发请求和数据库写入,不需要接收返回值赋值 authRepository.login(username, password) } catch (e: Exception) { // 自行处理请求异常 } } } } // AuthRepository 调整login方法为无返回值 class AuthRepository(private val database: xdb) { val auth: LiveData<List<AuthModel>> = Transformations.map(database.authDao.getAuthInfo()) { it.asDomainModel() } suspend fun login(username: String, password: String) { withContext(Dispatchers.IO) { val auth = Network.retrofitInstance?.create(AuthService::class.java) val i = auth?.doLogin(username, password)?.await() if (i != null) { database.authDao.insertAuthInfo(*i.asDatabaseModel()) } // 数据库写入完成后,DAO返回的LiveData会自动更新,auth变量同步变化 } } }
方案2:手动给ViewModel的LiveData赋值
如果你确实需要手动控制ViewModel中LiveData的赋值,修改login方法直接返回实际的List数据即可:
// AuthRepository修改login返回值为实际数据类型 suspend fun login(username: String, password: String): List<AuthModel>? { return withContext(Dispatchers.IO) { val auth = Network.retrofitInstance?.create(AuthService::class.java) val i = auth?.doLogin(username, password)?.await() if (i != null) { database.authDao.insertAuthInfo(*i.asDatabaseModel()) // 直接返回转换后的实际业务数据 i.asDomainModel() } else { null } } } // 此时赋值两侧类型匹配,不会再报错 _auth.value = authRepository.login(username, password)
内容的提问来源于stack exchange,提问作者vpbot
相关产品推荐
相关产品推荐

