You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现带参数的Room查询及对应Repository、ViewModel层逻辑

实现逻辑说明

非LiveData类型的Room同步查询为阻塞操作,禁止在主线程直接调用,必须在后台线程执行,以下是Repository与ViewModel层的完整实现方案:


1. Repository层实现

Kotlin版本

class MemberRepository(private val memberDao: MemberDao) {
    // 协程实现:挂起函数自动切IO线程执行查询
    suspend fun getPlayersForReselection(reselectedPlayerName: String): List<Member> {
        return withContext(Dispatchers.IO) {
            memberDao.getPlayersForReselection(reselectedPlayerName)
        }
    }

    // 回调实现:适合不使用协程的场景,自动切回主线程返回结果
    fun getPlayersForReselectionAsync(reselectedPlayerName: String, callback: (List<Member>) -> Unit) {
        Executors.newSingleThreadExecutor().execute {
            val result = memberDao.getPlayersForReselection(reselectedPlayerName)
            Handler(Looper.getMainLooper()).post {
                callback(result)
            }
        }
    }
}

Java版本

public class MemberRepository {
    private final MemberDao memberDao;
    private final ExecutorService executor = Executors.newSingleThreadExecutor();
    private final Handler mainHandler = new Handler(Looper.getMainLooper());

    // 定义结果回调接口
    public interface PlayerQueryCallback {
        void onQueryResult(List<Member> playerList);
    }

    public MemberRepository(MemberDao memberDao) {
        this.memberDao = memberDao;
    }

    public void getPlayersForReselection(String reselectedPlayerName, PlayerQueryCallback callback) {
        executor.execute(() -> {
            // 后台线程执行查询
            List<Member> result = memberDao.getPlayersForReselection(reselectedPlayerName);
            // 切回主线程返回结果
            mainHandler.post(() -> callback.onQueryResult(result));
        });
    }
}

2. ViewModel层实现

Kotlin版本

class MemberViewModel(private val repository: MemberRepository) : ViewModel() {
    // 使用viewModelScope自动管理协程生命周期,避免内存泄漏
    fun loadReselectPlayers(name: String, onResult: (List<Member>) -> Unit) {
        viewModelScope.launch {
            val playerList = repository.getPlayersForReselection(name)
            // 已自动回到主线程,可直接传递给UI层使用
            onResult(playerList)
        }
    }
}

提示:使用viewModelScope需要引入KTX扩展依赖:implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2"

Java版本

public class MemberViewModel extends ViewModel {
    private final MemberRepository repository;

    public MemberViewModel(MemberRepository repository) {
        this.repository = repository;
    }

    public void loadReselectPlayers(String name, MemberRepository.PlayerQueryCallback callback) {
        repository.getPlayersForReselection(name, callback);
    }
}

注意事项

  • 禁止直接在主线程调用DAO层的同步查询方法,Room默认会抛出主线程操作数据库的异常
  • 如果项目使用RxJava,可直接将DAO方法返回值改为Single<List<Member>>,Room原生支持RxJava类型返回值,无需手动处理线程切换

内容的提问来源于stack exchange,提问作者SteveC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 00:45:01