RxJava系列8:rxjava应用场景

rxjava应用场景

rxjava in retrofit

未使用rxjava时,我们如何使用retrofit

以一个登录请求为例:

  1. 在一个interface中声明一个接口请求
/**
 * 登陆账号
 */
@FormUrlEncoded
@POST("/maoyan/login")
Call> login(@FieldMap Map postMap);

2、构建一个Retrofit对象,通过Retrofit获取到Call

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BETA_URL)
        .addConverterFactory(GsonConverterFactory.create(new Gson()))
        .build();
final ApiService apiService = retrofit.create(ApiService.class);
Map params = new HashMap<>();
params.put("username","maoyan");
params.put("password","1313123");
apiService.login(params).enqueue(new Callback>() {
    @Override
    public void onResponse(Call> call, Response> response) {

    }

    @Override
    public void onFailure(Call> call, Throwable t) {

    }
});

这样就完成了一个登录请求。

使用rxjava时,我们如何使用retrofit

retrofit的开发者为我们提供了Adapter,可以支持将 OkHttpCall 转换为 Observable。源码分析见后期的retrofit源码分析。

1、在一个interface中声明一个接口请求

/**
 * 登陆账号
 */
@FormUrlEncoded
@POST("/maoyan/login")
Observable> login(@FieldMap Map postMap);

2、构建一个Retrofit对象,通过Retrofit获取到Observable
!注意在构建时需要指定callAdapterFactory为RxJavaCallAdapterFactory

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BETA_URL)
        .addConverterFactory(GsonConverterFactory.create(new Gson()))
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .build();
final ApiService apiService = retrofit.create(ApiService.class);
Map params = new HashMap<>();
params.put("username","maoyan");
params.put("password","1121212");
apiService.login(params)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber>() {

            @Override
            public void onNext(ApiResponse data) {
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onCompleted() {

            }
        });

可以看到执行网络请求和线程切换(网络请求执行在io线程、请求回调执行在UI主线程),以及请求结果的订阅回调,都是一个链式结构。
onNext是请求成功的回调;
onError是请求失败的回调;

RxBinding

是Android界网红公司Square,Jake Wharton大牛开发的一套将Android UI控件的事件响应转为RxJava Api的形式框架,以一种优雅的方式来处理事件响应。

1.基本用法
Android原生方式

Button b = (Button)findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

    }
});

rxbinding方式

Button b = (Button)findViewById(R.id.button);
RxView.clicks(b).subscribe(new Action1() {
    @Override
    public void call(Void aVoid) {

    }
});

2.防止重复点击

button = (Button) findViewById( R.id.bt ) ;

     RxView.clicks( button )
             .throttleFirst( 2 , TimeUnit.SECONDS )   //两秒钟之内只取一个点击事件,防抖操作
             .subscribe(new Action1() {
                 @Override
                 public void call(Void aVoid) {
                     Toast.makeText(MainActivity.this, "点击了", Toast.LENGTH_SHORT).show();
                 }
             }) ;

其他如倒计时、表单验证上,采用rxbinding也很方便。

rxlifecycle

为了解决rxjava引入导致的内存泄漏问题,我们一般的做法是在ondestory时,把请求取消订阅。

rxlifecycle可以很方便的解决这个问题。

class MyFragment extends RxFragment {
 void startHttpReq(){
 this.subscription = httpObservable()
 // 绑定声明周期,在界面退出后自动关闭
 .compose(bindToLifecycle()) 
 .subscribe(

 );
 }
}

也可以设定在特定的声明周期事件时关闭:

class MyFragment extends RxFragment {
 void startHttpReq(){
 this.subscription = httpObservable()
 // 当Fragment运行到onPause时候自动结束调用
 .compose(bindUntilEvent(FragmentEvent.PAUSE)) 
 .subscribe(
 );
 }
}

rx-preferences

将Android中的sharepreference采用rxjava做了封装。

/创建sharedPreference实例  
SharedPreferences mySP = getApplicationContext().getSharedPreferences("rx_sp_test", Context.MODE_PRIVATE);  
mySP.edit().putString("test_string","this is test rx string").commit();  

mySP.edit().putBoolean("test_boolean",true).commit();  
//将sharedPreference作为参数转换成RxSharedPreferences实例  
RxSharedPreferences rxPreferences = RxSharedPreferences.create(mySP);  

//获取保存的值  
Preference testString = rxPreferences.getString("test_string");  
Preference testBoolean = rxPreferences.getBoolean("test_boolean", false);  

//发射数据  
testString.asObservable()  
        .subscribe(new Action1() {  
            @Override  
            public void call(String username) {  
                Log.e(TAG, "test_string: " + username);  
            }  
        });  

testBoolean.asObservable()  
        .subscribe(new Action1() {  
            @Override  
            public void call(Boolean aBoolean) {  
                Log.e(TAG, "test_boolean: " + aBoolean);  
            }  
        });  

RxPermissions

rxjava实现的权限申请。

                        .request(Manifest.permission.READ_CALENDAR)//这里填写所需要的权限
                        .subscribe(new Action1() {
                            @Override
                            public void call(Boolean aBoolean) {
                                if (aBoolean) {//true表示获取权限成功(注意这里在android6.0以下默认为true)
                                    Log.i("permissions", Manifest.permission.READ_CALENDAR + ":" + 获取成功);
                                } else {
                                    Log.i("permissions", Manifest.permission.READ_CALENDAR + ":" + 获取失败);
                                }
                            }
                        });
            }

业务场景

最适合使用RxJava处理的四种场景
https://appkfz.com/2017/09/01/best-scene-use-rxjava/

怎么使用Rxjava处理一系列异步事件?
https://www.zhihu.com/question/53463552

Android RxJava 实际应用讲解:(无条件)网络请求轮询
https://www.jianshu.com/p/11b3ec672812

    public void test() {
        Observable.interval(3, 1, TimeUnit.SECONDS)
                .doOnNext(new Action1() {
                    @Override
                    public void call(Long aLong) {

                        CinemaAPI api = APIServiceProvider.create(CinemaAPI.class);
                        Observable> ob = api.getFocusList(true, MovieProApplication.movieProApplication.accountService.getToken());
                        ob.subscribeOn(Schedulers.io())
                                .observeOn(AndroidSchedulers.mainThread())
                                .subscribe(new Action1>() {
                                    @Override
                                    public void call(List focusCinemas) {

                                    }
                                }, new Action1() {
                                    @Override
                                    public void call(Throwable throwable) {

                                    }
                                });

                    }
                }).subscribe(new Observer() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Long aLong) {
                Log.d("...:nht...", aLong + "");
            }
        });


    }

Android RxJava 实际应用讲解:(有条件)网络请求轮询(结合Retrofit)
https://www.jianshu.com/p/dbeaaa4afad5

//todo Test
    public void test() {
        CinemaAPI api = APIServiceProvider.create(CinemaAPI.class);
        Observable> ob = api.getFocusList(true, MovieProApplication.movieProApplication.accountService.getToken());
        ob.repeatWhen(new Func1, Observable>() {
            @Override
            public Observable call(Observable observable) {
                return observable.flatMap(new Func1>() {
                    @Override
                    public Observable call(Void aVoid) {
                        if (retryCount1 > 3) {
                            return Observable.error(new Throwable("轮询结束"));
                        } else {
                            return Observable.just(1).delay(2000, TimeUnit.MILLISECONDS);
                        }
                    }
                });
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1>() {
                    @Override
                    public void call(List focusCinemas) {
                        retryCount1 = retryCount1 + 1;
                        Log.d(":nht...", "执行了");
                    }
                }, new Action1() {
                    @Override
                    public void call(Throwable throwable) {
                        Log.d(":nht...", "error");
                    }
                });


    }

12-25 09:23:15.105 7237-7237/com.sankuai.moviepro D/:nht...: 执行了
12-25 09:23:16.889 7237-7237/com.sankuai.moviepro D/:nht...: 执行了
12-25 09:23:18.937 7237-7237/com.sankuai.moviepro D/:nht...: 执行了
12-25 09:23:20.969 7237-7237/com.sankuai.moviepro D/:nht...: 执行了
12-25 09:23:23.021 7237-7237/com.sankuai.moviepro D/:nht...: 执行了
12-25 09:23:23.025 7237-7237/com.sankuai.moviepro D/:nht...: error

Android RxJava 实际应用讲解:网络请求嵌套回调
https://www.jianshu.com/p/5f5d61f04f96

Android RxJava 实际应用讲解:合并数据源 & 同时展示
https://www.jianshu.com/p/fc2e551b907c

Android RxJava 实际应用讲解:从磁盘 / 内存缓存中 获取缓存数据
https://www.jianshu.com/p/6f3b6b934787

Android RxJava 实际应用讲解:联合判断多个事件
https://www.jianshu.com/p/2becc0eaedab

RxJava系列番外篇:一个RxJava解决复杂业务逻辑的案例
https://segmentfault.com/a/1190000008011398

你可能感兴趣的:(RxJava)