Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/231.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Android中使用Room和RxJava链接多个网络调用和数据库插入_Java_Android_Rx Java2_Android Room - Fatal编程技术网

在Android中使用Room和RxJava链接多个网络调用和数据库插入

在Android中使用Room和RxJava链接多个网络调用和数据库插入,java,android,rx-java2,android-room,Java,Android,Rx Java2,Android Room,比如说,我有一个android应用程序,它有一个包含按钮的单一活动。当我单击按钮时,我想向RESTAPI发出几个请求,返回JSON响应。然后,我解析对java对象的响应,并将其保存到Room中。对于http请求,我实现了一个截击请求队列作为单例。 请求是异步的,并将其响应传递回UI线程。在那里,我给这些物体留了空间 我发送http请求的方式如下: RestService.requestSomeData(context, objectId, new ResponseListener() {

比如说,我有一个android应用程序,它有一个包含按钮的单一活动。当我单击按钮时,我想向RESTAPI发出几个请求,返回JSON响应。然后,我解析对java对象的响应,并将其保存到Room中。对于http请求,我实现了一个截击请求队列作为单例。 请求是异步的,并将其响应传递回UI线程。在那里,我给这些物体留了空间

我发送http请求的方式如下:

RestService.requestSomeData(context, objectId, new ResponseListener() {
    @Override
    public void onRestSuccess(String response) {    
        // parse response JSON
        // call the insert method
    }

    @Override
    public void onRestError(int code, String errorMessage) {
        // handle error
    }
}
由于Room强制您将查询分派给工作线程,因此我使用RxJava来处理该任务。因此,例如,我的Insert方法返回一个数组列表,该列表包含用
单个
包装的插入对象的ID。然后调用Insert方法并订阅结果,如下所示:

myDisposable = MyDatabase.getInstance().myDao()
    .insert(myObject)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(idList -> {
        Log.d(TAG, "IDs inserted: " + idList.toString());
    }, Throwable::printStackTrace);
但是,我希望将多个请求链接到服务器,然后在所有请求完成且DB插入就绪时收到通知,以便更新UI(例如,显示确认消息,禁用保存按钮)。我读了很多文章,但没有找到如何完成这项看似简单的任务。基本上,我想要实现的是:

// a some sort of container for all the observables I get from the database insertions
private Object aPoolOfObservables;

RestService.requestSomeData(context, objectId, new ResponseListener() {
    @Override
    public void onRestSuccess(String response) {    
        // parse response JSON

        aPoolOfObservables.add(MyDatabase.getInstance().myDao()
          .insert(myObject)
          .subscribeOn(Schedulers.io())
          .observeOn(AndroidSchedulers.mainThread()));
    }
}

// repeat this n-times more
...

aPoolOfObservables.subscribe(new Listener() {
    @Override
    public void onComplete() {
        // update UI
    }
});
然后多次执行此请求,并将响应添加到
单个
(或
可能
可流动
)响应的集合中,并不是订阅每个流,而是订阅集合,因为我只关心所有操作是否完成。通过在前一个版本的
onrestsucture
中触发请求来链接它们似乎是一个非常糟糕的解决方案。 您知道是否有一种RxJava机制允许这样做吗


是否有任何通用方法/设计模式来处理这种情况?我可以想到很多情况下,您希望仅在执行多个请求并交付结果后启用按钮。如何在RxJava的上下文中创建和订阅此类事件?我对反应式数据没有太多的研究,因此任何知识都将受到赞赏。

您可以将每个请求包装在一个
中,以存储每个请求的每个JSON响应。然后,使用
Single.zip(…)

私人合成可处置物品;
私人ArrayList单曲;
requestSomeData(上下文、objectId、新的ResponseListener(){
@凌驾
public void onRestSuccess(字符串响应){
//解析响应JSON
//kotlin语法
单打(
MyDatabase.getInstance().myDao().insert(myObject)
.flatMap{ids:ArrayList->
//转换单个以包含JSON响应
return@flatMap单个。仅(成对(ID、响应))
}
);
}
}
//kotlin语法
一次性用品(
//执行所有单打
Single.zip(singles){}.subscribe()
);

尝试使用
Observable.zip()
。它可以同时处理多个请求,并在所有请求完成时发出通知
private CompositeDisposable disposables;
private ArrayList<Single<Pair<ArrayList<Integer>, String>>> singles;

RestService.requestSomeData(context, objectId, new ResponseListener() {
    @Override
    public void onRestSuccess(String response) {    
        // parse response JSON

        // kotlin syntax
        singles.add(
            MyDatabase.getInstance().myDao().insert(myObject)
                .flatMap { ids: ArrayList<String> -> 
                    // transform single to include JSON response
                    return@flatMap Single.just(Pair(ids, response))
                }
        );
    }
}

// kotlin syntax
disposables.add(
    // execute all singles
    Single.zip(singles) {}.subscribe()
);