![](/img/trans.png)
[英]Infinite loop in PagingSource when response is empty using Paging 3 library and Retrofit
[英]Error 401 Retrofit when using Paging 3 library
在我嘗試使用 Paging 3 庫之前,我正在使用 Retrofit 撥打電話,我得到代碼 200 並且一切正常。然后,我嘗試實現 Paging 3 庫並使用 Retrofit ,我不知道為什么,我我收到錯誤 401。我嘗試了一些 Paging 3 示例,所有這些示例都沒有在 API 調用中使用標頭,使用 Paging 3 在 API 調用中添加標頭有什么問題嗎? 我不確定使用標頭是否存在問題,或者我只是在實現 Paging 3 庫時做錯了什么。
我的代碼:
服務:
interface APICalls{
@GET(MYAPIURL)
suspend fun getData(
@Header("Auth") auth : String,
@Query("pageSize") pageSize:Int
):Response<ResponseData>
}
楷模:
data class ResponseData(
@SerializedName("listData") val listData:MutableList<DataAPI>,
@SerializedName("pageSize") val pageSize : Int
):Serializable
data class DataAPI(
@SerializedName("id") val id:Int,
@SerializedName("data")val data: String
): Serializable
結果包裝:
class Result<out T:Any>{
data class Success<T:Any>(val value: T): Result<T>()
data class Failure(val message:String, val errorCode:Int?):Result<Nothing>()
}
尋呼源:
val responseData = mutableListOf<DataAPI>()
class DataAPIPagingSource(private val token:String,private val apiCalls:APICalls) : PagingSource<Int,DataAPI>{
override fun getRefreshKey(...):Int?{
return null
}
override suspend fun load(params : LoadParams<Int>):LoadResult<Int,DataAPI>{
return try{
val currentPage = params.key ?: 1
val response = apiCalls.getData(token)
response.body()?.let{
Result.Success(it)
}?: run{
Result.Failure(response.message(),response.code())
}
val data = response.body()?.listData ?: emptyList()
responseData.addAll(data)
LoadResult.Page(responseData,if(currentPage ==1) null else -1),currentPage.plus(1)
}catch(e:Exception){
LoadResult.Error(e)
}
}
}
視圖模型:
class DataViewModel(private val apiCalls:APICalls): ViewModel {
//I get this token in shared preference
val token = .....
val mydata = getDataList()
.map{pagingData -> pagingData.map{DataModel.DataItem(it)}}
private fun getDataList(){
return Pager(PagingConfig(25)){
DataAPIPagingSource(token,apiCalls)
}.flow.cachedIn(viewModelScope)
}
}
sealed class DataModel{
data class DataItem(val dataitem: DataAPI) : DataModel()
}
private val DataModel.DataItem.identificator : Int
get() = this.dataItem.id
分段:
class MyFragment : Fragment(){
private val myAdapter : DataAdapter by lazy{
DataAdapter()
}
private val viewModelFactory : ViewModelFactory by inject()
private val dataViewModel : DataViewModel by navGraphViewModels(R.id.nav_graph){viewModelFactory}
override fun onViewCreated(...){
super.onViewCreated(...)
binding.myRecyclerView.apply{
adapter = myAdapter
layoutManager = StaggeredGridLayoutManager(1,StaggeredGridLayoutManager.VERTICAL)
setHasFixedSize(true)
}
lyfecycleScope.launch{
dataViewModel.mydata.collect{myAdapter.submitData(it)}
}
}
}
適配器:
class DataAdapter : PagingDataAdapter<DataModel,RecyclerView.ViewHolder>(DataModelComparator){
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position:Int){
val dataModel : DataModel? = getItem(position)
dataModel.let{
when(dataModel){
is DataModel.DataItem ->{
val viewHolder = holder as DataItemViewHolder
viewHolder.binding.textview1.text = dataModel.dataitem.data
}
}
}
}
override fun getItemViewType(position:Int):Int{
return when(getItem(position)){
is DataModel.DataItem -> R.layout.item_data
null -> throw UnsupportedOperationException("Unknown view")
}
}
override fun onCreateViewHolder(...){
return when(viewType){
R.layout.item_data ->{
DataItemViewHolder(ItemDataBinding.inflate(...))
}
}
}
class DataItemViewHolder(val binding: DataItemBinding): RecyclerView.ViewHolder(binding.root)
companion object {
val DataModelComparator = object : DiffUtil.ItemCallback<DataModel>() {
override fun areItemsTheSame(oldItem: Movie, newItem: Movie): Boolean {
return oldItem.dataitem.id == newItem.dataitem.id
}
override fun areContentsTheSame(oldItem: DataModel, newItem: DataModel): Boolean {
return oldItem == newItem
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.