首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Java的LiveData使用分页库3

用Java的LiveData使用分页库3
EN

Stack Overflow用户
提问于 2020-07-14 13:00:16
回答 1查看 3.3K关注 0票数 3

我希望与LiveData一起使用分页库3。文档解释了如何使用Guava Futures, RxJava Singles and Kotlin Coroutines,但没有解释如何与来自Java的LiveData一起使用它。我可能可以通过各种PagingSource类提供loadloadSingleloadFuture

Kotlin中的load示例使用coroutine来加载数据,从而可以返回一个LoadResult对象。但是,对于LiveData,我需要从改造中进行异步调用,并设置LiveData对象的值。对于LiveData没有单独的LiveData实用程序方法,就像对于RxJavaGuava那样。那么,如何使用来自LiveDataJava实现这一点呢?

代码语言:javascript
复制
package org.metabrainz.mobile.data.repository;

import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.paging.PagingSource;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.metabrainz.mobile.data.sources.Constants;
import org.metabrainz.mobile.data.sources.api.MusicBrainzServiceGenerator;
import org.metabrainz.mobile.data.sources.api.SearchService;
import org.metabrainz.mobile.data.sources.api.entities.mbentity.MBEntity;
import org.metabrainz.mobile.data.sources.api.entities.mbentity.MBEntityType;
import org.metabrainz.mobile.presentation.features.adapters.ResultItem;
import org.metabrainz.mobile.presentation.features.adapters.ResultItemUtils;

import java.util.ArrayList;
import java.util.List;

import kotlin.coroutines.Continuation;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class SearchPagingSource extends PagingSource<Integer, ResultItem> {

    @NonNull
    private final static SearchService service = MusicBrainzServiceGenerator
            .createService(SearchService.class, true);
    @NonNull
    private MBEntityType entity;
    @NonNull
    private String searchTerm;

    public SearchPagingSource(@NonNull MBEntityType entity, @NonNull String searchTerm) {
        this.entity = entity;
        this.searchTerm = searchTerm;
    }

    @NotNull
    @Override
    public LiveData<LoadResult<Integer, ResultItem>> load(@NotNull LoadParams<Integer> loadParams,
                         @NotNull Continuation<? super LoadResult<Integer, ResultItem>> continuation) {

        Integer pageSize = loadParams.getLoadSize();
        Integer offset = loadParams.getKey() == null ? 0 : loadParams.getKey();

        MutableLiveData<LoadResult<Integer, ResultItem>> resultsLiveData = new MutableLiveData<>();
        service.searchEntity(entity.name, searchTerm, pageSize.toString(),
                String.valueOf(offset * pageSize))
                .enqueue(new Callback<ResponseBody>() {
                    @Override
                    public void onResponse(@NonNull Call<ResponseBody> call,
                                           @NonNull Response<ResponseBody> response) {
                        try {
                            List<ResultItem> data = ResultItemUtils
                                    .getJSONResponseAsResultItemList(response.body().string(), entity);

                            LoadResult.Page<Integer, ResultItem> loadResult
                                    = new LoadResult.Page<>(data, Math.max(0, offset - pageSize),
                                    offset + pageSize, LoadResult.Page.COUNT_UNDEFINED,
                                    LoadResult.Page.COUNT_UNDEFINED);
                            resultsLiveData.setValue(loadResult);
                        } catch (Exception e) {
                            e.printStackTrace();
                            LoadResult.Error<Integer, ResultItem> error = new LoadResult.Error<>(e);
                            resultsLiveData.setValue(error);
                        }
                    }

                    @Override
                    public void onFailure(@NonNull Call<ResponseBody> call, @NonNull Throwable t) {

                    }
                });
        return resultsLiveData;
    }


}

不过,这会在运行时崩溃。

代码语言:javascript
复制
org.metabrainz.android E/AndroidRuntime: FATAL EXCEPTION: main
    Process: org.metabrainz.android, PID: 2222
    java.lang.ClassCastException: androidx.lifecycle.MutableLiveData cannot be cast to androidx.paging.PagingSource$LoadResult
        at androidx.paging.PageFetcherSnapshot.doInitialLoad(PageFetcherSnapshot.kt:302)
        at androidx.paging.PageFetcherSnapshot$pageEventFlow$1.invokeSuspend(PageFetcherSnapshot.kt:149)
        at androidx.paging.PageFetcherSnapshot$pageEventFlow$1.invoke(Unknown Source:10)
        at androidx.paging.CancelableChannelFlowKt$cancelableChannelFlow$1.invokeSuspend(CancelableChannelFlow.kt:35)
        at androidx.paging.CancelableChannelFlowKt$cancelableChannelFlow$1.invoke(Unknown Source:10)
        at kotlinx.coroutines.flow.ChannelFlowBuilder.collectTo$suspendImpl(Builders.kt:327)
        at kotlinx.coroutines.flow.ChannelFlowBuilder.collectTo(Unknown Source:0)
        at kotlinx.coroutines.flow.internal.ChannelFlow$collectToFun$1.invokeSuspend(ChannelFlow.kt:33)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
        at kotlinx.coroutines.EventLoop.processUnconfinedEvent(EventLoop.common.kt:69)
        at kotlinx.coroutines.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:321)
        at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:26)
        at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:109)
        at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:158)
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:54)
        at kotlinx.coroutines.BuildersKt.launch(Unknown Source:1)
        at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47)
        at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source:1)
        at androidx.lifecycle.BlockRunner.maybeRun(CoroutineLiveData.kt:174)
        at androidx.lifecycle.CoroutineLiveData.onActive(CoroutineLiveData.kt:240)
        at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:437)
        at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:395)
        at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:361)
        at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:300)
        at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:339)
        at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:145)
        at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:131)
        at androidx.lifecycle.ReportFragment.dispatch(ReportFragment.java:68)
        at androidx.lifecycle.ReportFragment.dispatch(ReportFragment.java:144)
        at androidx.lifecycle.ReportFragment.onStart(ReportFragment.java:109)
        at android.app.Fragment.performStart(Fragment.java:2637)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1312)
        at android.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1549)
        at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1611)
        at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManager.java:3039)
        at android.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:2996)
        at android.app.FragmentController.dispatchStart(FragmentController.java:189)
        at android.app.Activity.performStart(Activity.java:7007)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2867)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2986)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1671)
        at android.os.Handler.dispatchMessage(Handler.java:108)
        at android.os.Looper.loop(Looper.java:206)
        at android.app.ActivityThread.main(ActivityThread.java:6784)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:852)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-16 20:45:37

我已经打开了一个特性请求,用于将LiveData寻呼源与分页库一起传送。我从Google收到了以下回复。

d.android.com上的Java示例用于Guava + LiveData,在我们使用的coroutine等效项中:番石榴的ListenableFuture作为一个异步原语返回单个结果(等效于Coroutine或RxJava单),LiveData用于多个结果/结果流(等效于Kotlin流,或RxJava可观察到)。

如果我想使用LiveData,建议我在下面的代码片段行中写一些东西。

代码语言:javascript
复制
abstract class SearchPagingSource extends RxPagingSource<Integer, ResultItem>() {

    @NotNull
    public abstract LiveData<LoadResult<Integer, ResultItem>> loadLiveData(params: LoadParams<Key>);

    @NotNull
    @Override
    public Single<LoadResult<Integer, ResultItem>> loadSingle(@NotNull LoadParams<Integer> loadParams) {
        return loadLiveData(params).toRxJavaSingle(); // You must implement this bit!
    }
}

在上面的片段中使用的LiveData应该是SingleLiveEvent

PS:如果有更多的开发人员提出要求,谷歌开发人员愿意重新考虑他们在图书馆中的立场。相关的谷歌问题追踪票是

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62895817

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档