问题描述
我有一个带有 CRUD 函数的 Room @Dao,声明如下:
interface IMutableDao<T> {
@RawQuery
fun syncbrokerGet(query: SupportsqliteQuery): T?
/////////////////////////////////////////////////////////////////////////////////////////////////////
@Insert(onConflict = OnConflictStrategy.ABORT)
suspend fun insert(e: T)
@Update
suspend fun update(e: T)
@Delete
suspend fun delete(e: T)
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun batchInsert(l: List<T>)
@Update
suspend fun batchUpdate(l: List<T>)
@Delete
suspend fun batchDelete(l: List<T>)
}
所有其他 DAO 类都实现了这个接口。
在一个单独的模块(动态功能)中,我获得了对上述 CRUD 函数的引用,我用它来使用反射插入/更新/删除记录,如下面的代码片段所示:
class EntityInfoExt(val nestName: String,val localizedname: String,val clazz: KClass<out ILorikeetDbEntity>,val daoGetter: () -> IMutableDao<out ILorikeetDbEntity>) {
private var dao: IMutableDao<out ILorikeetDbEntity>? = null
private val insertRef: KFunction<*> by lazy {
dao!!::class.functions.find {it.name.equals("insert",true)}!!
}
private val deleteRef: KFunction<*> by lazy {
dao!!::class.functions.find {it.name.equals("delete",true)}!!
}
private val updateRef: KFunction<*> by lazy {
dao!!::class.functions.find {it.name.equals("update",true)}!!
}
private val getRef: KFunction<*> by lazy {
dao!!::class.functions.find { it.name.equals("syncbrokerGet",true)}!!
}
private fun validateDao() {
if (dao == null) {
dao = daoGetter()
}
}
suspend fun insert(obj: ILorikeetDbEntity) {
try {
validateDao()
insertRef.invokeSuspend(dao!!,obj)
}
catch (e: Throwable) {
if (e is InvocationTargetException) {
throw e.targetException
}
else {
throw e
}
}
}
suspend fun update(obj: ILorikeetDbEntity) {
try {
validateDao()
updateRef.invokeSuspend(dao!!,obj)
}
catch (e: Throwable) {
if (e is InvocationTargetException) {
throw e.targetException
}
else {
throw e
}
}
}
suspend fun delete(obj: ILorikeetDbEntity) {
try {
validateDao()
deleteRef.invokeSuspend(dao!!,obj)
}
catch (e: Throwable) {
if (e is InvocationTargetException) {
throw e.targetException
}
else {
throw e
}
}
}
fun getobject(id: UUID): ILorikeetDbEntity? {
try {
validateDao()
return getRef.call(dao!!,SelectObjectQuery(nestName,id).query) as? ILorikeetDbEntity?
}
catch (e: Throwable) {
if (e is InvocationTargetException) {
throw e.targetException
}
else {
throw e
}
}
}
}
问题是,在我测试的某些设备中,它随机在其他设备上工作,函数引用不再有效,我不明白这是怎么发生的。下面的调用有时会起作用,而不会起作用,就像函数引用被重新定位......或类似的东西。 由于插入/更新函数被声明为挂起,因此调用是通过辅助方法进行的,调用如下:
funInsert = dao::class.functions.find {
it.name.equals("batchInsert",true)
}!!
funUpdate = dao::class.functions.find {
it.name.equals("batchUpdate",true)
}!!
funInsert.invokeSuspend(dao,objects)
函数 invokeSuspend 声明如下:
suspend fun KFunction<*>.invokeSuspend(obj: Any,vararg args: Any?): Any? =
suspendCoroutineUninterceptedOrReturn { cont ->
call(obj,*args,cont)
}
我无法理解的是有时会调用:
insert.invokeSuspend(dao,objects)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)