rxjava应用场景
以一个登录请求为例:
/**
* 登陆账号
*/
@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) {
}
});
这样就完成了一个登录请求。
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是请求失败的回调;
是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也很方便。
为了解决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(
);
}
}
将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);
}
});
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 extends Void> 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