如何在Android中压缩两个观测值?

如何在Android中压缩两个观测值?,android,kotlin,rx-java,Android,Kotlin,Rx Java,在我的应用程序中,我有两个服务,它们都有一个方法,可以发出请求,然后返回不同类型的可观察对象 我想在一个RecyclerView中显示一个列表,该列表由合并这两个观察值的结果组成。我在谷歌上搜索了一下,发现zip()方法似乎完全符合我的要求。我正在尝试实现它,但我不知道如何正确地实现它 当我在谷歌上搜索的时候,我想出了一个很好的解释。尽管作者使用的是单件,而我使用的是可观察的 据我所知,zip()是如何工作的,我知道我必须传递我想要“zip”的每个可观察对象,然后我必须指定一个函数来组成我的最终

在我的应用程序中,我有两个服务,它们都有一个方法,可以发出请求,然后返回不同类型的可观察对象

我想在一个RecyclerView中显示一个列表,该列表由合并这两个观察值的结果组成。我在谷歌上搜索了一下,发现zip()方法似乎完全符合我的要求。我正在尝试实现它,但我不知道如何正确地实现它

当我在谷歌上搜索的时候,我想出了一个很好的解释。尽管作者使用的是单件,而我使用的是可观察的

据我所知,
zip()
是如何工作的,我知道我必须传递我想要“zip”的每个可观察对象,然后我必须指定一个函数来组成我的最终可观察对象,对吗

这是我目前的代码:

interface InvitationService {
    @GET("foo/{userId}")
    fun getFooByUser(@Path("userId") userId: String): Observable<Response<ArrayList<Foo>>>
}

interface InvitationService {
    @GET("bar/{userId}")
    fun getBarByUser(@Path("userId") userId: String): Observable<Response<ArrayList<Bar>>>
}

class FooRemoteDataSource : FooDataSource {
    private var apiService: FooService

    fun getFooByUser(userId:String) {
        return apiService.getFooByUser(userId)
    }
}

class BarRemoteDataSource : BarDataSource {
    private var apiService: BarService

    fun getBarByUser(userId:String) {
        return apiService.getBarByUser(userId)
    }

}

class FooRepository(private val remoteDataSource: InvitationRemoteDataSource) : FooDataSource {

    override fun getFooByUser(userId: String): Observable<Response<ArrayList<Foo>>> {
        return remoteDataSource.getFooByUser(userId)
    }
}

class BarRepository(private val remoteDataSource: BarRemoteDataSource) : BarDataSource {

    override fun getBarByUser(userId: String): Observable<Response<ArrayList<Bar>>> {
        return remoteDataSource.getBarByUser(userId)
    }
}
我不知道如何正确调用
zip()
,我知道我必须传递一个函数,但我不明白,因为在上面链接的文章中,作者使用了
Function3
,因为他有3个可观察对象

因为我只有两个,我不知道怎么做。如果在方法args中的逗号后打开大括号,则需要我返回一个
BiFunction
,这是我不知道如何指定的

有人能给我解释一下吗?

对于Kotlin,您应该使用而不是RxJava
BiFunction
Function3
来自RxJava。使用RxKotlin,您可以使用lambdas


据我所知,zip()是如何工作的,我知道我必须传递我想要“zip”的每个可观察对象,然后我必须指定一个函数来组成我的最终可观察对象,对吗

正确,这里有一个简单的例子,演示了如何做

示例1

val observable1 = listOf(1, 2, 3).toObservable()
val observable2 = listOf(4, 5, 6).toObservable()
val zipped = Observables.zip(observable1, observable2) { o1, o2 -> o1 * o2}
在本例中,您有两个可观察对象,每个都发出整数。您将它们传递给
zip
,并将lambda作为第三个参数,该参数定义了一种“协同挖掘它们”的方法。在这种情况下,它们会成倍增加

压缩后的结果可见
将发出:4、10和18


示例2

这里是另一个压缩三个不同类型的观测值的示例:

val obs1 = listOf("on", "tw", "thre").toObservable()
val obs2 = listOf("n", "o", "e").toObservable()
val obs3 = listOf(1, 2, 3).toObservable()
val zipped = Observables.zip(obs1, obs2, obs3) { o1, o2, o3 -> 
    "$o1$o2 = $o3"
}

这里,生成的可观察对象的每个元素将是一个字符串:“一=1”、“二=2”、“三=3”

使用双函数压缩两个不同类型的可观察对象

override fun getCommoditiesAndAddresses() {
    view.showProgress()
    view.hideViews()
    Observable.zip(Commo24Retrofit.createAuthService(RateAPIService::class.java)
            .getCommodities(),
            Commo24Retrofit.createAuthService(RateAPIService::class.java)
                    .getLocations(GetLocationsRequest(getOrgId())),
            BiFunction { commodityResponse: GetCommoditiesResponse, locationsResponse: GetLocationsResponse ->
                handleCommoditiesAndAddresses(commodityResponse, locationsResponse)
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                view.hideProgress()
                view.showViews()
                view.handleCommodities(it?.commodities)
                view.handleLocations(it?.locations)
            }, { throwable ->
                view.hideProgress()
                view.handleFailure(throwable.getErrorMessage(context))
            })
}
看,我是如何处理回应的:

private fun handleCommoditiesAndAddresses(commodityResponse: GetCommoditiesResponse, locationsResponse: GetLocationsResponse): CommoditiesAddresses {
        return CommoditiesAddresses(commodityResponse.commodityList, locationsResponse.addressList)
    }
在这里,检查API服务:

interface RateAPIService {

    @POST("get-org-address")
    fun getLocations(@Body getLocationsRequest: GetLocationsRequest): Observable<GetLocationsResponse>

    @POST("get-commodity-list")
    fun getCommodities(): Observable<GetCommoditiesResponse>
    }
接口服务{
@POST(“获取组织地址”)
有趣的getLocations(@Body getLocationsRequest:getLocationsRequest):可观察
@POST(“获取商品列表”)
趣味商品():可观察
}

如果您有任何疑问,您可以将其注释掉。

如果我尝试,它将不起作用。在您的示例中,两个可观察对象来自同一类型!我的不是,我认为这就是问题所在,如果在方法中的逗号后打开大括号,它将要求我返回一个我不知道如何返回的双函数speciy@MarcosStival请使用rxKotlin而不是rxJava:好的,当我到家后,我会更改为rxKotlin,这不是太多开销吗?应该有一种更简单的方法来做我想做的事情,而不是使用zip方法,对吗?@MarcosStival,这取决于它。如果你想用Rx…zip做这件事,最好的方法是IMHO:)这篇文章是从2017年开始的,使用RxJava,今天你应该使用RxKotlin。请参见我关于如何执行的回答。:)好的,我一回到家就会做出改变@willimentzel成功了吗?:)谢谢你的评论,看起来你也得做同样的事情,我一到家就试试。谢谢是的,我必须做同样的事情,试试看,如果你有什么需要知道的,我会帮你的。它是MVP架构。我在演讲者中这样做。
interface RateAPIService {

    @POST("get-org-address")
    fun getLocations(@Body getLocationsRequest: GetLocationsRequest): Observable<GetLocationsResponse>

    @POST("get-commodity-list")
    fun getCommodities(): Observable<GetCommoditiesResponse>
    }