Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/207.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 如何从Observable手动请求事件?_Android_Retrofit_Rx Java_Observable_Rx Android - Fatal编程技术网

Android 如何从Observable手动请求事件?

Android 如何从Observable手动请求事件?,android,retrofit,rx-java,observable,rx-android,Android,Retrofit,Rx Java,Observable,Rx Android,我正在使用RxJava和reformation创建一个应用程序,在我的视图中,从服务器加载一个项目列表并显示给用户。用户可以通过单击刷新按钮来刷新数据。下面是使用MVP对我的场景的粗略实现 // This is my retrofit adapter service public interface ApiService{ @GET("items"); Observable<JsonElement> getItemsList(); } // This is my p

我正在使用
RxJava
reformation
创建一个应用程序,在我的视图中,从服务器加载一个项目列表并显示给用户。用户可以通过单击刷新按钮来刷新数据。下面是使用MVP对我的场景的粗略实现

// This is my retrofit adapter service
public interface ApiService{
    @GET("items");
    Observable<JsonElement> getItemsList();
}

// This is my presnter
public class MyPresnter{
    ...
    public Observable<List<Item>> loadItemsList(){
        return apiService.getItemsList().map(jsonElement -> {
            // here I convert my api response to a List of Items
            return new ArrayList<Item>();
        });
    }
}

// And inside my view I use RxBinding to bind my button click events
RxView.clicks(refreshBtn).subscribe(view -> mPresenter.loadItemsList()
                                            .subscribeOn(Schdulers.io())
                                            .observeOn(AndroidSchedulers.mainThread())
                                            .subscribe(list -> {/* update view */})
                                   );
//这是我的改装适配器服务
公共接口服务{
@获取(“项目”);
可观察的getItemsList();
}
//这是我的中心
公共级Myprescenter{
...
公共可观察负载项列表(){
返回apiService.getItemsList().map(jsonElement->{
//在这里,我将api响应转换为项目列表
返回新的ArrayList();
});
}
}
//在我的视图中,我使用RxBinding绑定我的按钮点击事件
RxView.clicks(刷新btn.subscribe(查看->mPresenter.loadItemsList())
.subscribeOn(schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(列表->{/*更新视图*/})
);
现在我的问题是,如果用户第一次进入视图,我应该如何在不单击刷新BTN的情况下请求数据?我是否应该使用刷新btn.performOnClick()?

或者有没有办法手动请求一个已经订阅的可观察对象的事件?

我想你可以调用
performOnClick
,前提是你事先设置了
RxView.clicks()

通常,您可能希望合并到一个
主题
,该主题也可以触发操作:

PublishSubject<Object> manualRefresh = PublishSubject.create();

RxView.clicks(refreshBtn)
.cast(Object.class)
.mergeWith(manualRefresh.onBackpressureLatest())
.switchMap(v -> mPresenter.loadItemsList()
                .subscribeOn(Schdulers.io())
                .observeOn(AndroidSchedulers.mainThread())
)
.subscribe(list -> /* update */);

manualRefresh.onNext("Now!");
PublishSubject手动刷新=PublishSubject.create();
RxView.点击次数(刷新BTN)
.cast(Object.class)
.mergeWith(手动刷新.onBackpressureLatest())
.switchMap(v->mPresenter.loadItemsList()
.subscribeOn(schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
)
.订阅(列表->/*更新*/);
manualRefresh.onNext(“现在!”);

我想您可以调用
performOnClick
,前提是您事先设置了
RxView.clicks()

通常,您可能希望合并到一个
主题
,该主题也可以触发操作:

PublishSubject<Object> manualRefresh = PublishSubject.create();

RxView.clicks(refreshBtn)
.cast(Object.class)
.mergeWith(manualRefresh.onBackpressureLatest())
.switchMap(v -> mPresenter.loadItemsList()
                .subscribeOn(Schdulers.io())
                .observeOn(AndroidSchedulers.mainThread())
)
.subscribe(list -> /* update */);

manualRefresh.onNext("Now!");
PublishSubject手动刷新=PublishSubject.create();
RxView.点击次数(刷新BTN)
.cast(Object.class)
.mergeWith(手动刷新.onBackpressureLatest())
.switchMap(v->mPresenter.loadItemsList()
.subscribeOn(schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
)
.订阅(列表->/*更新*/);
manualRefresh.onNext(“现在!”);

要回答这个问题,我们需要质疑流的逻辑。在前一种方法的subscribe方法中订阅新的可观察对象通常是不好的做法。在某些情况下,可能没有更好的解决办法,但这至少是一个调查的迹象。流的组合是RxJava的最大优势之一

这里的逻辑表明存在一系列事件(单击和手动调用),您希望通过订阅另一个流来响应这些事件。有一个操作符具有这种精确的行为,称为
flatMap

多亏了
flatMap
操作符,我们已经有了在发生某事时做出反应的方法:

refreshEventStream
    .flatMap(object -> {
        return mPresenter.loadItemsList().subscribeOn(Schdulers.io())
    })
    .subscribe(list -> /* update UI */)
现在,我们需要弄清楚什么东西实际上代表了什么。正如您所描述的,目前有两种方法可以调用刷新。通过单击事件和手动刷新。换句话说,我们希望将这些事件合并到一个流中。同样,我们可以使用一个名为
mergeWith
的漂亮而闪亮的操作符。然而,对于手动调用,我们需要创建Subject(),它的行为既像一个可观察对象,也像一个订阅者

 PublishSubject<Void> refreshSubject = PublishSubject.create()
 refreshEventStream = refreshSubject
                          .mergeWith(Rx.clicks(refreshBtn).throttleFirst(500, TimeUnit.MILLISECONDS))

 refreshEventStream
    .flatMap(object -> {
        return mPresenter.loadItemsList().subscribeOn(Schdulers.io())
    })
    .subscribe(list -> /* update UI */)
PublishSubject refreshSubject=PublishSubject.create()
refreshEventStream=refreshSubject
.mergeWith(Rx.clicks(刷新BTN).throttleFirst(500,时间单位.毫秒))
刷新事件流
.flatMap(对象->{
返回mPresenter.loadItemsList().subscribeOn(schedulers.io())
})
.订阅(列表->/*更新UI*/)

我在click流中添加了
throttleFirst
操作符,因为您可能不想让用户发送这样的请求:-)它所做的唯一一件事是从该流中获取一个事件,并在指定的时间内忽略其余的排放,然后再对其作出反应。

要回答这个问题,我们需要质疑这条流的逻辑。在前一种方法的subscribe方法中订阅新的可观察对象通常是不好的做法。在某些情况下,可能没有更好的解决办法,但这至少是一个调查的迹象。流的组合是RxJava的最大优势之一

这里的逻辑表明存在一系列事件(单击和手动调用),您希望通过订阅另一个流来响应这些事件。有一个操作符具有这种精确的行为,称为
flatMap

多亏了
flatMap
操作符,我们已经有了在发生某事时做出反应的方法:

refreshEventStream
    .flatMap(object -> {
        return mPresenter.loadItemsList().subscribeOn(Schdulers.io())
    })
    .subscribe(list -> /* update UI */)
现在,我们需要弄清楚什么东西实际上代表了什么。正如您所描述的,目前有两种方法可以调用刷新。通过单击事件和手动刷新。换句话说,我们希望将这些事件合并到一个流中。同样,我们可以使用一个名为
mergeWith
的漂亮而闪亮的操作符。然而,对于手动调用,我们需要创建Subject(),它的行为既像一个可观察对象,也像一个订阅者

 PublishSubject<Void> refreshSubject = PublishSubject.create()
 refreshEventStream = refreshSubject
                          .mergeWith(Rx.clicks(refreshBtn).throttleFirst(500, TimeUnit.MILLISECONDS))

 refreshEventStream
    .flatMap(object -> {
        return mPresenter.loadItemsList().subscribeOn(Schdulers.io())
    })
    .subscribe(list -> /* update UI */)
PublishSubject refreshSubject=PublishSubject.create()
refreshEventStream=refreshSubject
.mergeWith(Rx.clicks(刷新BTN).throttleFirst(500,时间单位.毫秒))
refre