上一次捣蛋 RxAndroid 是今年二月份的事情了,当时 RxAndroid 还处于一个资料甚少交流难的状态,当时还特地建了一个交流群,让搞这个的人能够加进来讨论讨论,毕竟这玩意仍是挺有意思的,因而到今天群里已经有 124 人。html
在这里我发现了一个现象,进入这个群的小伙伴不少都是中级工程师 or 以上的水准,没有像不少 XXXXXAndroid 交流群那样,小白和伸手党一大堆(在这里没有任何贬义看待,任何人都是从小白过来,只想说明一个现象)。嗯,是的,分层了,越是接触新颖的事物、并把事物专研进去的人才会有更大的概率发现并加入到这个组织。就像不少 HR,从古老的前程无忧到拉勾、周伯通、BOSS 直聘、100offer、github、甚至知乎等等新颖且汇集大量优秀工程师的地方招人同样,由于这些地方都汇集了热爱新潮和讨论的优秀人才。之后 HR 姐姐们也能够到各大框架的讨论区去挖人了 [笑哭]。git
将要重构的项目是本人的一个业余项目,因为上个公司工做太忙,致使进度缓慢,到如今功能点也还没完成多少个。趁着这几天失业,好好追追进度(工做还得要找,毕竟饭仍是要吃~),顺便重构一下以前考虑不周到 or 不规范的地方,在这里 RxAndroid 充当一个辅助做用,并非每一处地方都用上场,毕竟具体问题具体分析。github
登录功能重构以前 (只用 Retrofit 作请求):编程
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 |
public void onLogin(String phone, String psw) { mLoginPage.showProgressBar(); HttpUtils.getApiManager().login(phone, psw) .enqueue(new Callback<LoginResponse>() { @Override public void onResponse(Response<LoginResponse> response, Retrofit retrofit) { mLoginPage.hideProgressBar(); LoginResponse result = response.body(); if(result.error_code == 0){ if(saveUserInfo(result)){ Oxygen.getInstance().closeAllPopupPage(); }else{ mLoginPage.showSnackbar(" 未知错误 "); } }else{ mLoginPage.showSnackbar(result.error_msg); } } @Override public void onFailure(Throwable t) { mLoginPage.hideProgressBar(); handleError(t); } }); } private boolean saveUserInfo(LoginResponse response){ Oxygen.setUserInfo(response.data); return Oxygen.getUserInfo().save(); } |
流程大概是这样的:帐号密码请求服务器 —> 服务器返回用户资料(此处仅含 accessToken 和 refreshToken)—> 保存用户资料到本地(文件保存) —> 保存成功则登录成功,保存失败则登录失败。服务器
可见,我要等 UserInfo.getInstance().save() 的返回来做出判断登录成功与否,在这里,我放了在主线程去作,显然这样是会有性能问题。架构
办法 2:new Thread 去作这个保存,等待返回结果,而后再回到主 Thread 去更新 UI,大概是这样的:框架
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
private void saveUserInfo(final LoginResponse response){ new Thread(new Runnable() { @Override public void run() { Oxygen.setUserInfo(response.data); if(Oxygen.getUserInfo().save()){ ((Activity)context).runOnUiThread(new Runnable() { @Override public void run() { Oxygen.getInstance().closeAllPopupPage(); } }); }else{ ((Activity)context).runOnUiThread(new Runnable() { @Override public void run() { mLoginPage.showSnackbar(" 未知错误 "); } }); } } }).start(); } |
这样就把卡顿主线程的问题解决了,但~~~ 有没更直观、简单的方法?ide
RxAndroid !!函数
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 38 39 40 41 42 43 44 45 46 47 48 |
public void onLogin(String phone, String psw) { HttpUtils.getApiManager().login(phone, psw) .subscribeOn(Schedulers.io()) // 请求服务器在 io 线程 .map(new Func1<LoginResponse, String>() { @Override public String call(LoginResponse response) { if(response.error_code == 0){ return saveUserInfo(response) ? "" : " 未知错误 "; }else{ return response.error_msg; } } }) .observeOn(AndroidSchedulers.mainThread()) // 指定 doOnSubscribe 在主线程,若没有 finallyDo 可不加,不然必须加上 .doOnSubscribe(new Action0() { @Override public void call() { mLoginPage.showProgressBar(); } }) .finallyDo(new Action0() { @Override public void call() { mLoginPage.hideProgressBar(); } }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<String>() { @Override public void call(String result) { if(!TextUtils.isEmpty(result)){ mLoginPage.showSnackbar(result); }else{ Oxygen.getInstance().closeAllPopupPage(); } } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { handleError(throwable); } }); } private boolean saveUserInfo(LoginResponse response){ Oxygen.setUserInfo(response.data); return Oxygen.getUserInfo().save(); } |
响应式编程,一条链式反应,有专门处理请求前、数据返回后处理、请求完成处理、异常等等的函数,还能够给它们特指专门的线程,思路清晰多了。性能
俺身边有一位朋友可能因为单身多年,手速达到惊人地步,年轻人嘛,急,按个按钮总喜欢连续猛按几下,而页面也连续弹出几个。。。
1 2 3 4 5 6 7 8 9 10 |
RxAdapterView.itemClickEvents(mListView)
.throttleFirst(1, TimeUnit.SECONDS)
.subscribe(new Action1<AdapterViewItemClickEvent>() { @Override public void call(AdapterViewItemClickEvent adapterViewItemClickEvent) { if(mCallback != null){ mCallback.onOpenDetailPage(event.position()); } } }); |
throttleFirst 能帮咱们解决手速问题,如上。
注意,用了 RxBinding 以后,它就不单单是一个点击事件这么简单了,它成为了一个 Observable,然而咱们能够用上它的各类特异功能 duang 的一声解决问题。
细心的小伙伴们可能已经发现个人代码有点奇怪,不太像是在用传统的开发模式下作操做。对,我是在本身构建的一个 MVC 架构上作的,因为还不很很成熟,就先不放出来讨论,例如模块间的耦合度仍是挺大的,因此我想用 RxBus 当事件总线来解耦,这个考虑的东西比较多,先写到这里,未完待续。
推荐: