在Android上使用RxBus处理事件


介绍

直到最后一次,我从API获取数据并将其带到ViewModel。
这次,我将解释从ViewModel到View,事件处理的部分。

先决条件

有关此处描述的代码的前提条件,请参见此处。

关于事件处理的需要

必须从ViewModel通知View(活动和片段)异步处理(api等)的结果。
此时,如果在同步处理中接收到返回值,则主线程将被冻结。
另外,如果ViewModel具有View引用,则需要了解ViewModel的生命周期,并且
View是不必要的,因为ViewModel的单元测试需要View。
因此,我仅在View处于活动状态时使用事件来接收它。

选择RxBus的原因。

EventBus是用于处理事件的著名库。
这次使用RxBus的原因是
有一个故事说EventBus的通知很难理解,所以我选择了RxBus。

这是因为EventBus全局注册了事件,但是
现在看来,它取决于以下实现。
https://qiita.com/subaru44k/items/27cd4828edc65cd9d7a6

从这个意义上讲,考虑到学习成本,EventBus可能不错,但是
使用RxBus的另一个优点是可以将所使用的库与异步处理集成在一起。
没有理由仅仅因为您正在使用RxJava而使用RxBus,因此
RxJava和EventBus也可以。

我认为您应该做出适合团队情况的选择。

RxBus

的事件机制

在RxBus中,通过在您使用的位置(例如View和ViewModel)访问相同的RxBus实例,
它可以交换事件。
我尝试单例获取RxBus实例。
现在可以从任何地方松散地耦合事件注册和监视。

最初,Application有一个实例,但是
当我运行单元测试时,如果没有应用程序我将无法运行它,因此我将其设置为单例。
我想知道是否还可以,因为如果我使用Android Test运行测试,它会起作用,
我现在正在使用单例。

RxBus和生命周期

与View一起使用时,如果您没有在生命周期中释放已注册的事件,则
如果没有参考,可能会泄漏或导致错误。
稍后我将详细说明,但是当"活动"或"片段"落后或被释放时,
您还需要取消监视事件。

样例代码

RxBus实施。

首先,定义RxBus。
单击此处获取源。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    public class RxBus {
        private final PublishSubject<Object> bus = PublishSubject.create();
        private static RxBus rxBus;

        private RxBus() {

        }

        public static RxBus getInstance() {
            if (rxBus == null) {
                rxBus = new RxBus();
            }
            return rxBus;
        }

        public void send(final Object event) {
            bus.onNext(event);
        }

        public Observable<Object> toObservable() {
            return bus;
        }

        public boolean hasObservers() {
            return bus.hasObservers();
        }
    }

定义PublishSubject的实例,该实例实际注册事件,
定义为将其实例返回为单例。

使用RxBus

发送事件的示例

这是一个通过实际使用RxBus将异步从API获得的结果传递给View的过程。
单击此处获取源。

1
2
3
4
5
6
7
8
    GithubRepositoryApiCompleteEventEntity eventResult = new GithubRepositoryApiCompleteEventEntity();
    eventResult.setListItems(data);
    if (response.getItems() != null && response.getItems().size() > 0) {
            eventResult.setResult(true);
    }

    // イベントを呼び出す
    RxBus.getInstance().send(eventResult);

所获取的数据和获取结果存储在用于交换事件

GithubRepositoryApiCompleteEventEntity的实体中。
将此实例指定为事件参数并发送事件。

使用RxBus

接收事件的示例

这是接收RxBus发送的事件的过程。
单击此处获取源。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
            this.compositeDisposable = new CompositeDisposable();
            this.compositeDisposable.add(RxBus.getInstance()
                    .toObservable()
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Object>() {
                        @Override
                        public void accept(Object obj) {
                            if (obj instanceof GithubRepositoryApiCompleteEventEntity) {
                                // 結果をリスト表示
                                if (((GithubRepositoryApiCompleteEventEntity) obj).isResult()) {
                                    RecyclerView list = view.findViewById(R.id.githubRepositoryList);
                                    list.setLayoutManager(new LinearLayoutManager(view.getContext()));
                                    list.setAdapter(new GithubRepositoryListAdapter(((GithubRepositoryApiCompleteEventEntity) obj).getListItems()));
                                    list.setVisibility(View.VISIBLE);
                                    list.addItemDecoration(new DividerItemDecoration(view.getContext(), DividerItemDecoration.VERTICAL));
                                }
                                view.findViewById(R.id.progressBar).setVisibility(View.GONE);
                            }
                            // それ以外のイベントは処理しない
                        }
                    }));

            ExpApplication.getInstance().getViewModelLocator().getGithubRepositoryListViewModel().getRepositoryListData();

    // ?中略?

        @Override
        public void onStop() {
            super.onStop();
            this.compositeDisposable.clear();
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
            this.compositeDisposable.clear();
        }

定义

CompositeDisposable和的实例
为此设置RxBus事件接收处理。
通过使用onStop()或onDestroy()调用CompositeDisposable.clear()并取消监视,
可以沿生命周期进行处理。

RxBus事件接收处理先调用.toObservable(),然后调用
指定要使用.observeOn(AndroidSchedulers.mainThread())处理的线程。
由于我弄乱了屏幕,因此这次我使用的是主线程,但是
您也可以使用Schedulers.newThread()在不同于Main的线程中运行它。
.subscribe(new Consumer<Object>() {之后将描述特定的接收处理。

public void accept(Object obj) {以下是接收过程,但是
传输过程中指定的参数作为对象类型变量发送。
if (obj instanceof GithubRepositoryApiCompleteEventEntity) {,判断类型
确定这是否是您想要接收的事件。
如果是要接收的事件,将对其进行处理。

综上所述

因此,我试图解释RxBus。
下次,我想按房间解释sqLite。