您的当前位置:首页正文

RxJava for Android 开发使用的开源框架

来源:要发发知识网

RxJava 出来很久了,以至于现在大红大紫。在 Android 平台中的影响更是不可言语,很多新开源项目中也纷纷引入了她。但我一直因为各种原因没有动手揭开她神秘的面纱。目前 Rx (ReactiveX) 对 Android 支持已经非常强大, 从数据库到业务逻辑异步处理,再到与 MVP 设计模式的结合都已经有相对成熟解决方案。现在正是入手的好时机。现在网络上有关于 RxJava 的文章很多,在此就不累赘她的好处和使用方法,感兴趣可以自行学习。

说明: 本人对 RxJava 的理解不是很深刻,目前只处于会用的阶段。部分观点可能会有误导
本文要解决的问题: 对 RxJava 技术体系在 Android 实际项目中具体使用的理解

RxJava 理解

使用 Thread 实现:

new Thread() {
    @Override
    public void run() {
        super.run();
        for (File folder : folders) {
            File[] files = folder.listFiles();
            for (File file : files) {
                if (file.getName().endsWith(".png")) {
                    final Bitmap bitmap = getBitmapFromFile(file);
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            imageCollectorView.addImage(bitmap);
                        }
                    });
                }
            }
        }
    }
}.start();

通过 RxJava 的使用:

Observable.from(folders)
    .flatMap(new Func1<File, Observable<File>>() {
        @Override
        public Observable<File> call(File file) {
            return Observable.from(file.listFiles());
        }
    })
    .filter(new Func1<File, Boolean>() {
        @Override
        public Boolean call(File file) {
            return file.getName().endsWith(".png");
        }
    })
    .map(new Func1<File, Bitmap>() {
        @Override
        public Bitmap call(File file) {
            return getBitmapFromFile(file);
        }
    })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Action1<Bitmap>() {
        @Override
        public void call(Bitmap bitmap) {
            imageCollectorView.addImage(bitmap);
        }
    });

这里可以看出,使用 RxJava 能够很好的让代码逻辑变的简单。RxJava 的操作方式乍一看很像 Builder 模式,在创建类的时候先给类添加各种初始化参数,然后调用 Build 创建对象。然而 RxJava 每一步都有相应的动作(action),既都会对上一个动作返回的数据做出必要的处理,然后将变化的数据传递下去。subscribe() 方法在末尾调用,最终数据会在这里被使用。可以认为 subscribe() 被调用后,就会启动上面一连串动作(这样理解对于初学者就够)。
上面例子中用到的那些方法只要理解了,基本上 RxJava 就可以正常使用。有问题再查看官方文档。

关于rxjava的一些记录

Func1 和 Action1 的区别在于, Func1 包装的是有返回值的方法。另外,和 ActionX 一样, FuncX 也有多个,用于不同参数个数的方法。FuncX 和 ActionX的区别在 FuncX 包装的是有返回值的方法。

线程控制

Observable.just(1,2,3,4) 
.subscribeOn(Schedulers.io()) 
.observeOn(Schedulers.newThread())
.map(doSomething) // 执行在 newThread 中
.observeOn(AndroidSchedulers.mainThread) 
.subscribe(subscriber); // 执行在 UI 线程中

observeOn()指定的是 Subscriber的线程,而这个 Subscriber并不是subscribe()参数中的 Subscriber,而是 observeOn()执行时的当前 Observable所对应的 Subscriber ,即它的直接下级 Subscriber 。换句话说,observeOn()指定的是它之后的操作所在的线程

Sqlbrite

例子:

Observable<Query> users = db.createQuery("users", "SELECT * FROM users");
users.subscribe(new Action1<Query>() {
  @Override public void call(Query query) {
    Cursor cursor = query.run();
    // TODO parse data...
  }
});

因为作者的初衷并不是为了简化对 SQLite 的操作,也没有打算完全透明对 SQL 的使用。所以个人感觉不是很好用,我更乐意使用 GreenDao 。

Retrofit

一款现在很流行的网络请求地方库。使用起来很简单。

public interface GitHubService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}

Retrofit retrofit = new Retrofit.Builder()
    
    .build();

GitHubService service = retrofit.create(GitHubService.class);

另外关注以下几个关键字:

  • @GET
  • @Path
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);
  • @Query
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
  • @QueryMap
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
  • @Body

EventBus 与 RxJava 的选择

该库的设计初衷是在 Activities, Fragments, Threads, Services 等模块间轻松的建立链接。降低两个模块之间的耦合性,通过事件进行模块间通信。同时支持异步操作。

RxJava 被设计出来的初衷也是为了解决异步任务。并且通过流式编写,让一连串任务依次执行。虽然 RxJava 是通过观察者模式订阅事件。但如果抛开被观察者和观察者的概念,通过代码流式风格的编写来理解 RxJava 设计思想,似乎也是可以的。

问题又回到了原点,EventBus 和 RxJava 该如何选择呢?个人理解 RxJava 确实能从代码的角度清晰业务逻辑。事件的处理有事件序列来控制,能很清楚展示一个事件从开始处理到结束所经历的操作,并且可以根据需要控制事件在哪个 Thread 中被处理。当项目的业务很复杂的时候,我们会选择将业务逻辑进行隔离。业务内部使用 RxJava 处理,业务之间可以通过 EventBus 来进行消息传递。这样能使业务完全解耦。

RxJava 与 MVP

  • 编写 Contract 接口存放 IView 接口和 Presenter 接口
public interface Contract {

    interface View extends BaseView<Presenter> {

        // 更新UI的操作接口
    }

    interface Presenter extends BasePresenter {

        // 业务相关数据操作接口
    }
}

public interface BasePresenter {

    void subscribe();

    void unsubscribe();

}

public interface BaseView<T> {

    void setPresenter(T presenter);

}
  • Fragment 实现 Contract.View 接口
  • Custom Presenter 实现 Contract.BasePresenter 接口
  • 在 Custom Presenter 使用 RxJava 编写业务逻辑