android_框架_Rxjava_应用场景

rxjava应用场景

转载自:https://blog.csdn.net/a910626/article/details/79311611

rxjava in retrofit

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

以一个登录请求为例:

  1. 在一个interface中声明一个接口请求
    /**
     * 登陆账号
     */
    @FormUrlEncoded
    @POST("/maoyan/login")
    Call<ApiResponse<Login>> login(@FieldMap Map<String, String> 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<String,String> params = new HashMap<>();
    params.put("username","maoyan");
    params.put("password","1313123");
    apiService.login(params).enqueue(new Callback<ApiResponse<Login>>() {
    
    
        @Override
        public void onResponse(Call<ApiResponse<Login>> call, Response<ApiResponse<Login>> response) {
    
    
            
        }
     
        @Override
        public void onFailure(Call<ApiResponse<Login>> call, Throwable t) {
    
    
            
        }
    });

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

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

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

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

    /**
     * 登陆账号
     */
    @FormUrlEncoded
    @POST("/maoyan/login")
    Observable<ApiResponse<Login>> login(@FieldMap Map<String, String> 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<String,String> params = new HashMap<>();
    params.put("username","maoyan");
    params.put("password","1121212");
    apiService.login(params)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<ApiResponse<Login>>() {
    
    
                 
                @Override
                public void onNext(ApiResponse<Login> 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<Void>() {
    
    
        @Override
        public void call(Void aVoid) {
    
    
    
        }
    });

2.防止重复点击

    button = (Button) findViewById( R.id.bt ) ;
    
         RxView.clicks( button )
                 .throttleFirst( 2 , TimeUnit.SECONDS )   //两秒钟之内只取一个点击事件,防抖操作
                 .subscribe(new Action1<Void>() {
    
    
                     @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<String> testString = rxPreferences.getString("test_string");  
    Preference<Boolean> testBoolean = rxPreferences.getBoolean("test_boolean", false);  
      
    //发射数据  
    testString.asObservable()  
            .subscribe(new Action1<String>() {
    
      
                @Override  
                public void call(String username) {
    
      
                    Log.e(TAG, "test_string: " + username);  
                }  
            });  
      
    testBoolean.asObservable()  
            .subscribe(new Action1<Boolean>() {
    
      
                @Override  
                public void call(Boolean aBoolean) {
    
      
                    Log.e(TAG, "test_boolean: " + aBoolean);  
                }  
            });  

##RxPermissions

rxjava实现的权限申请。

                            .request(Manifest.permission.READ_CALENDAR)//这里填写所需要的权限
                            .subscribe(new Action1<Boolean>() {
    
    
                                @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<Long>() {
    
    
                        @Override
                        public void call(Long aLong) {
    
    
    
                            CinemaAPI api = APIServiceProvider.create(CinemaAPI.class);
                            Observable<List<FocusCinema>> ob = api.getFocusList(true, MovieProApplication.movieProApplication.accountService.getToken());
                            ob.subscribeOn(Schedulers.io())
                                    .observeOn(AndroidSchedulers.mainThread())
                                    .subscribe(new Action1<List<FocusCinema>>() {
    
    
                                        @Override
                                        public void call(List<FocusCinema> focusCinemas) {
    
    
    
                                        }
                                    }, new Action1<Throwable>() {
    
    
                                        @Override
                                        public void call(Throwable throwable) {
    
    
    
                                        }
                                    });
    
                        }
                    }).subscribe(new Observer<Long>() {
    
    
                @Override
                public void onCompleted() {
    
    
    
                }
    
                @Override
                public void onError(Throwable e) {
    
    
    
                }
    
                @Override
                public void onNext(Long aLong) {
    
    
                    Log.d("...:nht...", aLong + "");
                }
            });
    
    
        }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lhCu8k5H-1602670295681)(http://7xvzr8.com1.z0.glb.clouddn.com/QQ20171222-0@2x.png)]

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

    //todo Test
        public void test() {
    
    
            CinemaAPI api = APIServiceProvider.create(CinemaAPI.class);
            Observable<List<FocusCinema>> ob = api.getFocusList(true, MovieProApplication.movieProApplication.accountService.getToken());
            ob.repeatWhen(new Func1<Observable<? extends Void>, Observable<?>>() {
    
    
                @Override
                public Observable<?> call(Observable<? extends Void> observable) {
    
    
                    return observable.flatMap(new Func1<Void, Observable<?>>() {
    
    
                        @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<List<FocusCinema>>() {
    
    
                        @Override
                        public void call(List<FocusCinema> focusCinemas) {
    
    
                            retryCount1 = retryCount1 + 1;
                            Log.d(":nht...", "执行了");
                        }
                    }, new Action1<Throwable>() {
    
    
                        @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

猜你喜欢

转载自blog.csdn.net/qq_42420293/article/details/123768159