Android:使用repeatWhen、takeUntil和带改造的过滤器通过rx-java无限滚动

2023-12-19

我正在使用 Retrofit 2.2 和 RxJava。 分页是这样工作的:我得到第一批数据,我必须请求具有相同参数的第二批数据,除了最后更新日期,然后如果我得到空或同一批数据,则意味着有没有更多的物品。我发现了这篇很棒的文章https://medium.com/@v.danylo/server-polling-and-retrying-failed-operations-with-retrofit-and-rxjava-8bcc7e641a5a#.40aeibaja https://medium.com/@v.danylo/server-polling-and-retrying-failed-operations-with-retrofit-and-rxjava-8bcc7e641a5a#.40aeibaja关于如何去做。所以我的代码是:

private Observable<Integer> syncDataPoints(final String baseUrl, final String apiKey,
        final long surveyGroupId) {
    final List<ApiDataPoint> lastBatch = new ArrayList<>();
    Timber.d("start syncDataPoints");
    return loadAndSave(baseUrl, apiKey, surveyGroupId, lastBatch)
            .repeatWhen(new Func1<Observable<? extends Void>, Observable<?>>() {
                @Override
                public Observable<?> call(final Observable<? extends Void> observable) {
                    Timber.d("Calling repeatWhen");
                    return observable.delay(5, TimeUnit.SECONDS);
                }
            })
            .takeUntil(new Func1<List<ApiDataPoint>, Boolean>() {
                @Override
                public Boolean call(List<ApiDataPoint> apiDataPoints) {
                    boolean done = apiDataPoints.isEmpty();
                    if (done) {
                        Timber.d("takeUntil : finished");
                    } else {
                        Timber.d("takeUntil : will query again");
                    }
                    return done;
                }
            })
            .filter(new Func1<List<ApiDataPoint>, Boolean>() {
                @Override
                public Boolean call(List<ApiDataPoint> apiDataPoints) {
                    boolean unfiltered = apiDataPoints.isEmpty();
                    if (unfiltered) {
                        Timber.d("filtered");
                    } else {
                        Timber.d("not filtered");
                    }
                    return unfiltered;
                }
            }).map(new Func1<List<ApiDataPoint>, Integer>() {
                @Override
                public Integer call(List<ApiDataPoint> apiDataPoints) {
                    Timber.d("Finished polling server");
                    return 0;
                }
            });
}

private Observable<List<ApiDataPoint>> loadAndSave(final String baseUrl, final String apiKey,
        final long surveyGroupId, final List<ApiDataPoint> lastBatch) {
    return loadNewDataPoints(baseUrl, apiKey, surveyGroupId)
            .concatMap(new Func1<ApiLocaleResult, Observable<List<ApiDataPoint>>>() {
                @Override
                public Observable<List<ApiDataPoint>> call(ApiLocaleResult apiLocaleResult) {
                    return saveToDataBase(apiLocaleResult, lastBatch);
                }
            });
}


private Observable<ApiLocaleResult> loadNewDataPoints(final String baseUrl, final String apiKey,
        final long surveyGroupId) {
    Timber.d("loadNewDataPoints");

    return Observable.just(true).concatMap(new Func1<Object, Observable<ApiLocaleResult>>() {
        @Override
        public Observable<ApiLocaleResult> call(Object o) {
            Timber.d("loadNewDataPoints call");
            return restApi
                    .loadNewDataPoints(baseUrl, apiKey, surveyGroupId,
                            getSyncedTime(surveyGroupId));
        }
    });
}

正如你所看到的,有趣的方法是loadNewDataPoints,我希望它被调用,直到没有更多的数据点。如你看到的Observable.just(true).concatMap是一个黑客,因为如果我删除这个连续映射restApi.loadNewDataPoints(....)虽然在日志中我可以看到 api 确实被调用,但没有被调用,但使用相同的旧参数,当然它返回与第一次相同的结果,因此同步停止,saveToDataBase 确实被调用得很好。通过我的黑客,它可以工作,但我想了解为什么它不能以其他方式工作,以及是否有更好的方法来做到这一点。多谢!


因此,我编写了此类 API(称为 Keyset Pagination)并针对它们实现了 Rx 客户端。

这是BehaviorSubjects 有用的情况之一:

S initialState = null;
BehaviorProcessor<T> subject = BehaviorProcessor.createDefault(initialState);
return subject
  .flatMap(state -> getNextElements(state).singleOrError().toFlowable(), Pair::of, 1)
  .serialize()
  .flatMap(stateValuePair -> {
      S state = stateValuePair.getLeft();
      R retrievedValue = stateValuePair.getRight();
      if(isEmpty(retrievedValue)) {
         subject.onComplete();
         return Flowable.empty();
      } else {
         subject.onNext(getNextState(state, retrievedValue));
         return Flowable.just(retrievedValue);
      }
    }
   .doOnUnsubscribe(subject::onCompleted)
   .map(value -> ...)

Here

  • getNextElement基于状态执行网络调用并返回具有单个值的反应流
  • isEmpty判断返回值是否为空,表示元素结束
  • getNextState将传入的状态与检索到的值相结合来确定下一个状态getNextElement.

如果发生错误(它将被传播)并且您在结束之前取消订阅(查询将被终止),它将正常工作。

当然,在您的具体情况下,这些不需要是单独的方法或复杂的类型。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android:使用repeatWhen、takeUntil和带改造的过滤器通过rx-java无限滚动 的相关文章

  • 如何为整个 Android 应用程序设置默认字体系列

    我在我的应用程序中使用 Roboto 浅色字体 要设置字体 我必须添加android fontFamily sans serif light 到每一个视图 有没有办法将 Roboto 字体声明为整个应用程序的默认字体系列 我已经尝试过这样的
  • 使用服务时应用程序终止时音乐暂停

    我正在使用一个Service类在后台播放音乐 当我在顶部显示通知栏时 我的应用程序出现问题 当我终止该应用程序时 音乐停止约 1 秒 然后再次开始 我不知道出了什么问题 我正在关注this https www simplifiedcodin
  • 接收广播意图时出错 { act=android.bluetooth.device.action.FOUND flg=0x10}

    我搜索了一下 没有发现任何相似的东西 我正在 Android 中使用蓝牙开发两个设备之间的连接 在 ACTION FOUND 方法上 当我尝试使设备信息显示在 listView 上时 我在 logcat 上收到该错误 德萨菲奥活动 公共类
  • Paypal 支付页面布局在 webview android 中损坏

    我在某些 Android 设备上遇到一个奇怪的问题 我正在 webview 上打开 PayPal 支付页面 但它的布局在某些设备上被破坏 请任何人有任何想法 请提出建议 我被困住了 该截图设备的浏览器为chrome版本34 0 1847 1
  • Android-无法解析符号 BaseObservable

    我正在尝试在 android 中实现数据绑定示例并使用可绑定变量创建 POJO 但我收到此错误 请帮忙 我正在关注这个教程http www vogella com tutorials AndroidDatabinding article h
  • Android Volley 服务器错误

    I am posting data all strings to varchar variables in server but i am getting volley server error or badnetwork performa
  • 如何从 AccountManager.getAccounts() 获取与特定帐户关联的图标

    每个帐户的帐户设置中都会显示一个图标 对于 Google 帐户有一个图标 对于 Facebook 帐户有另一个图标 有没有办法从应用程序的代码中获取该图标 最后我解决了 private Drawable getIconForAccount
  • EditText 的可绘制右侧

    下面是我的布局
  • 具有待处理意图的警报管理器

    下面的代码片段 public void onCreate Bundle savedInstanceState super onCreate savedInstanceState setContentView R layout main Do
  • android-透明RelativeLayout

    我想要制作一个具有可绘制渐变作为背景的活动 并将在其背景顶部显示 4 个面板 相对布局 现在我想让 4 个面板透明 例如 50 以便也可以看到渐变背景 我搜索了谷歌 但我发现只能通过活动而不是布局来做到这一点 如何做我想做的事 您可以创建一
  • 解析 android-21 的数据失败,不支持major.minor 版本 51.0

    安装 Android 5 0 SDK 21 后在 Eclipse 中出现以下错误 Loading data for Android 5 0 has encountered a problem Parsing Data for android
  • 索尼 SmartWatch 2 定制表盘自固件更新后损坏

    我知道这将是这个的重复 gt SW2 更新后如何修复 Sony SmartWatch 2 上的自定义表盘时间 https stackoverflow com questions 27536415 how to fix custom watc
  • 在 Android 媒体播放器上播放 MediaStore 中的音频

    有没有办法通过使用 MediaPLayer 播放从 MediaStore 获得的音频 或者我走的方向完全错误 到目前为止 我已经查看了 MediaStore Audio 但没有什么能真正帮助我 我只需要知道我是否走在正确的轨道上 首先 我假
  • 如何检测屏幕何时关闭?

    是否可以检测屏幕何时关闭并捕获它 我想在 Android 的全局设置中将计时器设置为 15 秒 我正在尝试查找一些如何捕获唤醒锁定模式的信息 只需注册您的应用程序即可执行操作Intent ACTION SCREEN OFF https de
  • Apache POI 的 ProGuard 设置

    我正在构建一个使用 Apache POI 库的应用程序 当我调试应用程序 在不运行 Proguard 的情况下编译它 时 一切都运行良好 但是在导出 APK 后 当我运行应用程序并打开 Excel 文件时 出现以下异常 RuntimeExc
  • NestedScrollView 中带有 RecyclerView 的 ItemTouchHelper:拖动滚动不起作用

    我已经实现了 ItemTouchHelper 如本文所述 https medium com ipaulpro drag and swipe with recyclerview b9456d2b1aaf k7xm7amxi https med
  • 使用 Android 2.x 进行实时音频流传输

    我需要在 2 x 及更高版本的设备上播放直播 This http developer android com guide appendix media formats html声明不可能在 Android 2 x 的设备上播放直播 我在这里
  • Firebase:获取对第一个项目/元素的引用

    我正在尝试获取对 firebase Array 中第一个项目的引用 就我而言 它会是 ElmmycgjS1Nvq albums IrdMMds 但我不确定如何构造查询 dbRef child ElmmycgjS albums child n
  • 是否可以从 Android Studio 恢复被覆盖的文件?

    由于错误 我覆盖了我的两个来自 android studio 的具有相同名称的项目 并且今天我已经取消了该操作 我尝试打开主项目 但发现其中没有 Java 类 只有布局文件 在我覆盖的第二个项目中 文件存在巨大混乱 并尝试使用 Androi
  • 以编程方式暂时禁用自动更新

    我有一个自行车计算机应用程序 可以在用户骑行时记录数据 我有一位用户报告了一个我没有考虑到的问题 他出去进行了一次长途骑行 100 多英里 但在外出记录数据时 该应用程序通过 Google Play 自动更新进行了更新 不幸的是 这导致应用

随机推荐

  • 为什么 OpenXML 读取行两次

    我计算两个工作表中的行数 如下所示 foreach WorksheetPart worksheetPart in workbookPart WorksheetParts OpenXmlPartReader reader new OpenXm
  • 当 selectedItem 为 null 时,在 Combobox 中显示“选择一项”

    我有一个绑定到 viewModel 对象列表的 WPF 组合框 最初 SelectedItem 为空 因此组合框显示为空白 当所选项目为空时 我希望组合框显示 选择项目 以引导用户从组合框中选择某些内容 有点像这样 一些文本框包含灰色文本
  • Flexbox 中的行换行中心对齐

    目前 我正在尝试使用 Flexbox 将列居中 但当我调整浏览器大小时 它会粘在左侧 我尝试过调整内容中心和对齐项目中心 但我可能没有将它们放在正确的位置 如果有人知道如何解决这个问题 将不胜感激 谢谢你 wrap display flex
  • 无法完成交付

    我在尝试完成已发布的交付时收到以下错误 我可以从目标网站做些什么吗 cleartool Error Unable to check out vobs amit sumit lost found pcs i ltf odfc set sftp
  • 如何使用 javaparser 获取类级别变量声明?

    我只想获取类级别的变量声明 如何使用 javaparser 获取声明 public class Login private Keyword browser private String pageTitle Login 使用javaparse
  • 为 GridView 添加捏缩放功能

    我需要为该 gridview 添加捏缩放 我没有找到任何有关在 gridview 中添加捏缩放的示例 到目前为止 我的布局如下所示 我需要向该 gridview 添加捏缩放 活动 main xml
  • 张量流中的CUDA_ERROR_OUT_OF_MEMORY

    当我开始训练一些神经网络时 它满足了CUDA ERROR OUT OF MEMORY但训练可以继续进行 不会出现错误 因为我想根据实际需要使用GPU内存 所以我设置了gpu options allow growth True 日志如下 I
  • 如何超链接到 .ppt 文件的特定幻灯片?

    我想链接到在线 PowerPoint 文件中的特定幻灯片 例如http www example com hello ppt 但我想要的是 当人们点击我的链接时 它会直接转到第 n 张幻灯片 这可能吗 Link to http www wha
  • html2canvas 不渲染 CDN 图像

    我正在尝试使用 html2canvas 获取屏幕截图 它对于文本工作正常 但它不渲染 CDN 图像 如果我在服务器中托管图像 它工作正常 但如果尝试从 CDN 链接加载图像 则这些图像不会渲染 我的代码是 索引 php div img sr
  • 从 Android 应用程序共享图像

    我正在尝试分享我的 Android 应用程序中的图像 我正在尝试将其作为电子邮件附件以及 WhatsApp 上的照片发送 代码是 String imageUrl Path to image eg sdcard pictures image1
  • 在 Django 数据库中存储整数数组

    在 django 数据库中存储整数数组的最佳方法是什么 我正在使用数组字段 https docs djangoproject com en 2 1 ref contrib postgres fields querying arrayfiel
  • Python,argparse:如何使 nargs=2 与 type=str 和 type=int

    我花了一些时间在 argparse 文档上 但我仍然在为我的程序中的一个选项使用这个模块而苦苦挣扎 parser add argument r rmsd dest rmsd nargs 2 help extract the poses th
  • Vagrant 配置错误 - “必须指定一个框。”

    盒子工作得很好 然后我停止了其中一个 当时唯一一个正在运行的 现在我无法让它们中的任何一个恢复 Running vagrant up name 给我以下错误 无论我选择哪个或是否将其保留在vagrant up让他们俩都出现 There ar
  • 头文件中的 Lambda 错误

    在我的一堂课上 我尝试使用std priority queue与指定的 lambda 进行比较 pragma once include
  • 将变量注入回调函数作用域

    是否可以将变量添加到回调范围 我想要实现的是 Foo prototype bar function fn var baz baz fn call this Foo bar function console log baz gives baz
  • 如何异步使用“WinHttp.WinHttpRequest.5.1”?

    代码 var WinHttpReq OleVariant procedure TForm1 Button1Click Sender TObject begin WinHttpReq CreateOleObject WinHttp WinHt
  • 在wxPython中查找文本大小的正确方法

    我正在使用 wxPython 开发一个应用程序 该应用程序的一部分在网格中创建大量 TextCtrl 以便为任意大的人员列表输入一周中的每一天的四字母代码 我已经设法让它发挥作用 但我不得不做一些笨拙的事情 具体来说 我还没有找到一种好的方
  • 网络音频 api 以不同的速率播放嘟嘟声、嘟嘟声、...嘟嘟声

    我试图根据浏览器窗口内的一些传感器读数以不同的速率播放 嘟嘟 声 这个想法是当传感器读数高时更快地 嘟嘟 嘟嘟 嘟 嘟 当传感器读数低时更慢地 嘟 嘟 所有这些都是实时的 传感器读数通过 socket io 输入浏览器 我已经可以控制进度条
  • JS 中的数独求解器

    我正在尝试编写一种可以解决数独的算法 目前 我的代码可以正常工作 直到 SupplyGrid 的数量耗尽为止 当这种情况发生时 它应该返回并尝试另一个号码 对吧 老实说 我不知道如何实现这一目标 var grid 0 0 0 0 0 0 0
  • Android:使用repeatWhen、takeUntil和带改造的过滤器通过rx-java无限滚动

    我正在使用 Retrofit 2 2 和 RxJava 分页是这样工作的 我得到第一批数据 我必须请求具有相同参数的第二批数据 除了最后更新日期 然后如果我得到空或同一批数据 则意味着有没有更多的物品 我发现了这篇很棒的文章https me