Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

集成Paging3时,paging3 不生效,无法进行网络请求操作 #4

Closed
KXwonderful opened this issue Nov 9, 2022 · 3 comments
Closed

Comments

@KXwonderful
Copy link

在项目中集成 Paging 3,但用在这个框架里发现并不能触发请求操作,参考代码如下:

// interface apiService
@GET("/xxx/xxx")
fun getList(@Query("page") page: Int,@Query("num") num: Int): Call<List<TestBean>>

// PagingSource
class TestPagingSource(private val apiService: ApiService) : PagingSource<Int, TestBean>() {
    override fun getRefreshKey(state: PagingState<Int, FaultLogBean>): Int? = null

    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, TestBean> {
        return try {
            LogUtils.e("paging load")  // 2. 并没有走这里的方法
            val page = params.key ?: 1
            val pageSize = params.loadSize
            val testList= apiService.getList(page, pageSize).await()
            val prevKey = if (page > 1) page - 1 else null
            val nextKey = if (testList.isNotEmpty()) page + 1 else null
            LoadResult.Page(testList, prevKey, nextKey)
        } catch (e: Exception) {
            LoadResult.Error(e)
        }
    }
}

// TestRepository
val pageSize = 10
fun getTestList(): Flow<PagingData<TestBean>> {
    return Pager(
        config = PagingConfig(pageSize),
        pagingSourceFactory = { TestPagingSource(apiService) }
    ).flow
}

// intent or event
sealed class TestEvent {
    data class GetTestList(val pagingData: Flow<PagingData<TestBean>>? = null) : TestEvent()
}

//  dispatcher 
class TestRequester : MviDispatcherKTX<TestEvent>() {
    ...
    is TestEvent.GetTestList -> sendResult(event.copy(testRepo.getTestList()))
}

// ui
class TestFragment {
    override fun onInput() {
        testRequest.input(TestEvent.GetTestList()) // 1. 触发请求
    }

    override fun onOutput() {
        // 3. 这里收不到消息
        testRequest.output(this) { testEvent ->
            // ...
        }
    }
}

如果用传统的 ViewModel 测试是没问题,可以触发,参考代码如下:

// viewModel
@HiltViewModel
class TestViewModel @Inject constructor(
    private val testRepo: TestRepository,
) : ViewModel() {

    fun getTestList(): Flow<PagingData<TestBean>> {
        return testRepo.getTestList().cachedIn(viewModelScope)
    }
}

// ui
class TestFragment {
    override fun onInitView() {
        lifecycleScope.launch {
            testViewModel.getTestList().collect { adapter.submitData(it) }
        } // 这边是ok的
    }
}
@KunMinX
Copy link
Owner

KunMinX commented Nov 9, 2022

// dispatcher
class TestRequester : MviDispatcherKTX() {
...
is TestEvent.GetTestList -> sendResult(event.copy(testRepo.getTestList()))
}

可以看看此处的 testRepo.getTestList() 后边是否遗漏了 .cachedIn(viewModelScope) 所致,

另外 paging 有自己独立的 flow 作为返回,适合传统方式使用,
如果要走 Dispatcher 的 input output(这里面是 Dispatcher 自身的 shareFlow 及其 collect,而非 paging 的 flow 和 collect),建议是在 Dispatcher 中调用 paging flow 的 collect,再将 “普通的实体类对象” 作为结果 sendResult 回推。

(对此可参考 complexRequest 案例:is ComplexIntent.ResultTest2 -> timer(1000).collect { sendResult(event) }

@KXwonderful
Copy link
Author

// dispatcher class TestRequester : MviDispatcherKTX() { ... is TestEvent.GetTestList -> sendResult(event.copy(testRepo.getTestList())) }

可以看看此处的 testRepo.getTestList() 后边是否遗漏了 .cachedIn(viewModelScope) 所致,

和这个没关系的。

主要原因还是在 viewModelScope 作用域中并不能成功消费 PagingData,只能在 Activity 或者 Fragment 中 collect 才会触发paging3中数据请求,因此在 Dispatcher 中也无法分发 PagingData。

(对此可参考 complexRequest 案例:is ComplexIntent.ResultTest2 -> timer(1000).collect { sendResult(event) }

这个案例用在 PagingData 的回推也是无效。

@KunMinX
Copy link
Owner

KunMinX commented Nov 10, 2022

感谢反馈,暂时建议传统方式。后续如有破局的好招,欢迎随时补充。

@KunMinX KunMinX closed this as completed May 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants