首页 > 解决方案 > 通过改造和分页进行多个 Api 调用

问题描述

我正在尝试使用带有改造的分页。但是我必须多次调用过滤或更改流动站(它是美国国家航空航天局的图片应用程序)。但是我的应用程序每秒都会调用 Api,这会导致它崩溃。我用 livedata 也用 flow 试过,但没有用。

使用 View Pager 在选项卡布局中有三个片段执行相同的流程,它们是curiousFragment、SpiritFragment、OpportunityFragment

object RetrofitInstance {

    private val moshi = Moshi.Builder()
        .add(KotlinJsonAdapterFactory())
        .build()

    private val retrofit by lazy {
        Retrofit.Builder()
            .baseUrl(BASE_URL)
           .addConverterFactory(MoshiConverterFactory.create(moshi)).baseUrl(BASE_URL)
          .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()

    }
    val api : SimpleApi by lazy {
        retrofit.create(SimpleApi::class.java)
    }}
interface SimpleApi {

    @GET("mars-photos/api/v1/rovers/{name}/photos?sol=1000&api_key=DEMO_KEY")
    fun getPhotos(@Path("name") name : String,
                  @Query("per_page")per_page:Int?,
                  @Query("page") page: Int):

            Single<AllPhotos>
class DataSource(name:String) : RxPagingSource<Int,Photo>(){

    var name :String
    init{
        this.name = name

    }

    override fun getRefreshKey(state: PagingState<Int, Photo>): Int? {
        return null
    }

    override fun loadSingle(params: LoadParams<Int>): Single<LoadResult<Int, Photo>> {

        val page = params.key ?:1
        return RetrofitInstance.api.getPhotos(name,params.loadSize,page)
            .subscribeOn(Schedulers.io())
            .map {toLoadResult(it,page)}
            .onErrorReturn { LoadResult.Error(it) }
    }

    private fun toLoadResult(data: AllPhotos,page : Int):LoadResult<Int,Photo>{
        return  LoadResult.Page(
            data = data.photos,
            prevKey = if(page==1) null else page-1,
            nextKey = page.plus(1)
        )
    }
}
class ViewModelDataSource (application: Application):AndroidViewModel(application) {
    
          fun getPhotosLiveData(name : String):LiveData<PagingData<Photo>>{
        return Pager(
            config = PagingConfig(pageSize = 10),
            pagingSourceFactory = {
                DataSource(name)

            },

            ).liveData
    }
    }



class CuriosityFragment : Fragment() {
    private lateinit var binding:FragmentCuriosityBinding
    lateinit var mApiViewModel : ViewModelDataSource
 
    private lateinit var curiosityAdapter: AdapterCuriosity
    var hasLoadedOnce = false

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        binding = FragmentCuriosityBinding.inflate(inflater,container,false)
        mApiViewModel = ViewModelProvider(this).get(ViewModelDataSource::class.java)
      

        setupRecyclerView()
        loaddata()
     
        return binding.root
    }
    fun setupRecyclerView(){
            curiosityAdapter = AdapterCuriosity()
            binding.recyclerViewCriosity.apply {
                adapter = curiosityAdapter
                layoutManager = LinearLayoutManager(requireContext())
            }



    }
    fun loaddata(){
        
        mApiViewModel.getPhotosLiveData("curiosity").observe(viewLifecycleOwner, Observer {
            curiosityAdapter.submitData(this.lifecycle,it)})

    }

class OpportunityFragment : Fragment() {

    private lateinit var binding: FragmentOppurtunityBinding
    private lateinit var mApiViewModel: ViewModelDataSource
    private lateinit var recyclerView: RecyclerView

    private lateinit var opportunityAdapter:AdapterOpportunity
    
    var hasLoadedOnce = false


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        binding = FragmentOppurtunityBinding.inflate(inflater, container, false)
        recyclerView = binding.recyclerViewOpportunity
        

        mApiViewModel = ViewModelProvider(this).get(ViewModelDataSource::class.java)
    

        setupRecyclerView()
        loaddata()
        setHasOptionsMenu(true)
        return binding.root
    }
    fun setupRecyclerView(){
        opportunityAdapter = AdapterOpportunity()
        binding.recyclerViewOpportunity.apply {
            adapter = opportunityAdapter
            layoutManager = LinearLayoutManager(requireContext())
        }

    }


    fun loaddata(){
        
           mApiViewModel.getPhotosLiveData("opportunity").observe(viewLifecycleOwner, Observer {
                opportunityAdapter.submitData(this.lifecycle,it)})



    }

class SpiritFragment : Fragment() {

    private lateinit var binding: FragmentSpiritBinding
    private lateinit var mApiViewModel : ViewModelDataSource
    private lateinit var spiritAdapter:AdapterSpirit
    lateinit var recyclerView: RecyclerView
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentSpiritBinding.inflate(inflater, container, false)
        recyclerView = binding.recyclerViewSpirit
        mApiViewModel = ViewModelProvider(this).get(ViewModelDataSource::class.java)
       

        setupRecyclerView()
        loaddata()
        setHasOptionsMenu(true)
        return binding.root
    }

    fun setupRecyclerView(){
        spiritAdapter = AdapterSpirit()
        binding.recyclerViewSpirit.apply {
            adapter = spiritAdapter
            layoutManager = LinearLayoutManager(requireContext())
        }

    }


    fun loaddata(){

    

        mApiViewModel.getPhotosLiveData("spirit").observe(viewLifecycleOwner, Observer {
            spiritAdapter.submitData(this.lifecycle,it)})


    }

标签: androidretrofitrx-javaandroid-livedataandroid-paging

解决方案


推荐阅读