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

如何通过Hilt提供带动态query参数的ExamplePagingSource依赖?

解决Hilt结合动态Query创建PagingSource的问题

核心问题在于Pager要求每次调用pagingSourceFactory时必须返回全新的PagingSource实例,你之前复用实例修改query的方式直接违反了这个规则,因此抛出异常。下面是两种符合Hilt规范的解决方案:

方案一:使用@AssistedInject(推荐,Hilt官方动态参数注入方案)

1. 改造ExamplePagingSource的构造器

用@AssistedInject标记构造方法,固定依赖ExampleBackendService使用普通@Inject注入,动态变化的query用@Assisted标记:

class ExamplePagingSource @AssistedInject constructor(
    private val backend: ExampleBackendService,
    @Assisted private val query: String
) : PagingSource<Int, DataItem>() {
    // ... 你的PagingSource业务实现逻辑
}

2. 创建AssistedFactory接口

定义一个工厂接口并标记@AssistedFactory,用于动态生成带query参数的PagingSource实例:

@AssistedFactory
interface ExamplePagingSourceFactory {
    fun create(query: String): ExamplePagingSource
}

3. 在ViewModel中注入工厂并配置Pager

在ViewModel里注入ExamplePagingSourceFactory,然后在Pager的pagingSourceFactory中调用工厂的create方法,每次都会生成全新的PagingSource实例:

@HiltViewModel
class YourViewModel @Inject constructor(
    private val pagingSourceFactory: ExamplePagingSourceFactory
) : ViewModel() {
    // 用StateFlow管理动态变化的查询参数
    private val _currentQuery = MutableStateFlow("initial_query")
    val currentQuery = _currentQuery.asStateFlow()

    val flow = currentQuery.flatMapLatest { query ->
        Pager(PagingConfig(pageSize = 20)) {
            pagingSourceFactory.create(query)
        }.flow
    }.cachedIn(viewModelScope)

    // 搜索操作:更新query触发重新创建Pager和PagingSource
    fun onSearch(query: String) {
        _currentQuery.value = query
    }
}

方案二:直接注入固定依赖+动态创建实例

如果不想使用AssistedInject,也可以在ViewModel中直接注入ExampleBackendService,然后在Pager的工厂方法里直接实例化PagingSource——这完全符合Hilt的使用逻辑,固定依赖由Hilt管理,动态参数按需传入,每次都生成新实例:

@HiltViewModel
class YourViewModel @Inject constructor(
    private val backend: ExampleBackendService
) : ViewModel() {
    private val _currentQuery = MutableStateFlow("initial_query")
    val currentQuery = _currentQuery.asStateFlow()

    val flow = currentQuery.flatMapLatest { query ->
        Pager(PagingConfig(pageSize = 20)) {
            ExamplePagingSource(backend, query)
        }.flow
    }.cachedIn(viewModelScope)

    fun onSearch(query: String) {
        _currentQuery.value = query
    }
}

为什么之前的setter方式不行?

Pager调用refresh()时,会重新执行你传入的pagingSourceFactory获取新实例。如果你复用同一个PagingSource对象仅修改query,Pager会检测到实例重复并抛出IllegalStateException——因为PagingSource内部维护了分页状态(如当前页码、加载状态),复用实例会导致状态混乱,因此Pager强制要求每次提供全新实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 07:35:07