处理 Paging3 中的 HttpException Android

Handle HttpException in Paging3 Android

我有一个 PagingSource 这样的:

class NotificationPagingSource(
    private val tayehAPI: TayehAPI,
    private val token: String,
) : PagingSource<Int, Notification>() {
    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Notification> {
        val nextPageNumber = params.key ?: STARTING_PAGE_INDEX

        return try {
            val response = tayehAPI.getNotifications(
                tokenString = token,
                page = nextPageNumber,
                perPage = params.loadSize
            )
            val notifications = response.objects

            LoadResult.Page(
                data = notifications,
                prevKey = if (nextPageNumber == STARTING_PAGE_INDEX) null else nextPageNumber - 1,
                nextKey = if (notifications.isEmpty()) null else nextPageNumber + 1
            )
        } catch (e: IOException) {
            LoadResult.Error(e)
        } catch (e: HttpException) {
            LoadResult.Error(e)
        }
    }

    override fun getRefreshKey(state: PagingState<Int, Notification>): Int? {
        return state.anchorPosition?.let { anchorPosition ->
            val anchorPage = state.closestPageToPosition(anchorPosition)
            anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1)
        }
    }
}

我想处理像 403 或 404 这样的 HttpException。我该如何实现?

您需要像这样将 addLoadStateListener 添加到分页适配器:

notificationAdapter.addLoadStateListener { loadState ->
            val errorState = when {
                loadState.append is LoadState.Error -> loadState.append as LoadState.Error
                loadState.prepend is LoadState.Error ->  loadState.prepend as LoadState.Error
                loadState.refresh is LoadState.Error -> loadState.refresh as LoadState.Error
                else -> null
            }
            errorState?.let {
                if (errorState.error.localizedMessage == "HTTP 403 Forbidden") {
                    AlertDialog.Builder(requireContext())
                        .setMessage(R.string.token_expire)
                        .setPositiveButton("Ok") { _, _ ->
                            findNavController().navigate(
                                NotificationFragmentDirections.actionGlobalHomeFragment()
                            )
                        }
                        .setCancelable(false)
                        .create()
                        .show()

                }
            }
        }

我在 的基础上提出了这个改进的解决方案。 我相信处理 HTTP 代码比处理错误消息文本更好。

notificationAdapter.addLoadStateListener { loadState ->
    val errorState = when {
        loadState.prepend is LoadState.Error -> loadState.prepend as LoadState.Error
        loadState.append is LoadState.Error -> loadState.append as LoadState.Error
        loadState.refresh is LoadState.Error -> loadState.refresh as LoadState.Error
        else -> null
    }

    when (val throwable = errorState?.error) {
        is IOException -> { /* Handle IO exceptions */ }
        is HttpException -> {
            if (throwable.code() == 401) { /* Handle HTTP 401 */ }
            else { /* Do something else */ }
        }
   }
}