你知道RxJava也可以实现AsyncTask吗?
使用RxJava实现异步操作(AsyncTask)
常见的异步操作我们可以联想到AsyncTask
或者handler
,其实google创造出的目的也就是为了让代码更加清晰明了,让代码更加简洁.
而Rx系列的出现也就为了实现代码的逻辑清晰,结构简单问题.在gitHub上的介绍是 a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库)
没错,就是这样,我们可以通过他的操作符,通过他的线程切换,来实现各种Android上遇到的问题.如异步任务,事件总线,数据处理,Retrofit框架等.
提出需求
AsyncTask是异步操作最常见的处理方式,几乎只要涉及到网络请求的,或者耗时操作的,都会使用到AsyncTask
,下面看看一个小需求.
- 给一个接口(查询IP)
http://ip.taobao.com/service/getIpInfo.php- 请求参数是
IP地址: ip=192.168.0.1- 功能实现
请求时弹出进度框,请求完成隐藏进度框,并Toast出获取到的数据(需要将数据封装成bean).
常见的异步操作AsyncTask
下面我们使用AsyncTask
来实现提出的需求.talk is cheap,请看代码.
//点击发出请求
comTitleStartTv.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {asyncTask();}});
具体的AsyncTask
处理如下.
private void asyncTask() {new AsyncTask<String, Void, IPInfo>() {@Overrideprotected IPInfo doInBackground(String... params) {// 在后台请求接口,并对请求到的json进行校验,解析成jsonString resultJsonStr = OkHttpUtil.get(Constants.ipUrl + getParam(params));IPInfo infos = null;if (resultJsonStr != null && !"".equals(resultJsonStr)) {infos = new Gson().fromJson(resultJsonStr, IPInfo.class);}return infos;}@Overrideprotected void onPreExecute() {super.onPreExecute();// 请求过程耗时操作,弹出Loading的进度框.if (dialog == null) {dialog = ProgressDialog.show(MainActivity.this, "Loading...", "正在加载...", true, false);}}@Overrideprotected void onPostExecute(IPInfo info) {// 请求完成,关闭进度框,并Toask请求后的结果数据.if (dialog != null)CHelper.disimissDialog(dialog);if (info != null) {Toast.makeText(MainActivity.this, "AsyncTask:" + info.toString(), Toast.LENGTH_SHORT).show();}}}.execute("192.168.0.1");}protected String getParam(String... p) {return "?ip=" + p[0];}
下面是AsyncTask的效果.
RxJava封装的异步操作
下面使用到了RxJava的操作符有线程切换subscribeOn
,observeOn
,doOnSubscribe
,doOnCompleted
,doOnError
.
- 封装BaseRxTask,主要是抽取公共方法和封装共性的功能.
如:getBaseDilogView
主要是封装进度框,处理了io和UI线程.
/*** @Author: Relice* BaseRX 异步任务基类*/
public abstract class BaseRxTask<D, P> {/*** 参数数组*/protected P[] p;protected Context mContext;private boolean needDialog = false;private ProgressDialog dialog;/*** 接口不需要传参数 复写此方法*/protected BaseRxTask(Context context, boolean needDialog) {this.mContext = context;this.needDialog = needDialog;}/*** 接口需要传参数调 复写此方法** @param context 上下文* @param needDialog 是否显示进度* @param p 参数数组*/@SafeVarargsprotected BaseRxTask(Context context, boolean needDialog, P... p) {this.mContext = context;this.needDialog = needDialog;this.p = p;}protected Observable<D> doInBackgroundObserVable() {return doInBackground();}public Observable<D> execute() {return getBaseDilogView();}/*** 进度View** @return*/private Observable<D> getBaseDilogView() {Observable<D> tObservable = doInBackgroundObserVable();//subscribeOn(Schedulers.io())事件所产生的线程,也就是subscribe所发生的线程.return tObservable.subscribeOn(Schedulers.io())//doOnSubscribe的作用是如它后面有subscribeOn(),那么它将执行
//离它最近的subscribeOn()所指定的线程,也就是下面的 //observeOn(AndroidSchedulers.mainThread())线程..doOnSubscribe(new Action0() {@Overridepublic void call() {if (needDialog && mContext != null) {dialog = ProgressDialog.show(mContext, "Loading...", "正在加载...", true, false);}}
// 注意这里添加了doOnCompleted,doOnError两个预处理的操作,
//所以在后面对Observable的订阅就要用subscribe(new Observer),如果使用subscribe(new Action)会报错.}).doOnCompleted(new Action0() {@Overridepublic void call() {CHelper.disimissDialog(dialog);}}).doOnError(new Action1<Throwable>() {@Overridepublic void call(Throwable throwable) {CHelper.disimissDialog(dialog);}})
//为了让进度框可以在UI线程里执行,影响了上面doOnSubscribe的线程.observeOn(AndroidSchedulers.mainThread());}protected abstract Observable<D> doInBackground();/*** 接口没参数空实现即可** @param p 参数数组*/protected abstract String getParam(P... p);/*** @return BaseUrl*/protected abstract String getBaseUrl();
}
实现BaseRxTask
因为在基类对所以的操作都封装好了,所以对BaseRxTask的实现就很简单了,代码中都有注释.public class GetRxIPInfoTask extends BaseRxTask<IPInfo, String> {protected GetRxIPInfoTask(Context context, boolean needDialog) {super(context, needDialog); }public GetRxIPInfoTask(Context context, boolean needDialog, String... p) {super(context, needDialog, p); }@Override public Observable<IPInfo> execute() {return super.execute(); }@Override protected Observable<IPInfo> doInBackground() {return Observable.create(new Observable.OnSubscribe<IPInfo>() {@Overridepublic void call(Subscriber<? super IPInfo> subscriber) {if (!subscriber.isUnsubscribed()) {String resultJsonStr = OkHttpUtil.get(nullToEmpty(getBaseUrl()) + nullToEmpty(getParam(p)));if (resultJsonStr != null && !"".equals(resultJsonStr)) {IPInfo infos = new Gson().fromJson(resultJsonStr, IPInfo.class);subscriber.onNext(infos);subscriber.onCompleted();} else {subscriber.onCompleted();}}}}); }private String nullToEmpty(String str) {return (str == null) ? "" : str; }/*** ip** @param p 参数数组*/ @Override protected String getParam(String... p) {return "?ip=" + p[0]; }/*** @return base url*/ @Override protected String getBaseUrl() {return Constants.ipUrl; } }
如何去调用
机智的你们可以看到在基类中的execute()方法封装了 进度框的功能,
public Observable<D> execute() {return getBaseDilogView();}
具体调用看下面代码
private void rxAsyncTask() {new GetRxIPInfoTask(MainActivity.this, true, new String[]{"192.168.0.1"}).execute()//提前过滤掉不想要的数据
// .filter(new Func1<IPInfo, Boolean>() {// @Override
// public Boolean call(IPInfo ipInfo) {// return ipInfo == null;
// }
// }).subscribe(new Observer<IPInfo>() {@Overridepublic void onCompleted() {System.out.println("onCompleted");}@Overridepublic void onError(Throwable e) {System.out.println("Throwable:" + e.getMessage());}@Overridepublic void onNext(IPInfo infos) {System.out.println("onNext:" + infos.toString());Toast.makeText(MainActivity.this, "RxAsyncTask:" + infos.toString(), Toast.LENGTH_SHORT).show();}});}
最后我们看看RxAsyncTask的效果.
你知道RxJava也可以实现AsyncTask吗?相关推荐
- Android开发,你所不知道的Android原生开发的现状
此外还有许多针对Android的非关系型的数据库,例如Realm,Parse,Firebase,ObjectBox等(其中有些仍在使用SQLite).如果我没记错的话,它们中的大多数(甚至全部)都具有 ...
- 敢问路在何方?国外安卓大神对Android原生开发现状剖析
点击上方"终端研发部",选择"星标" 回复"资源",领取全网最火的Java核心知识总结~ 前言 原文地址:The State of Nati ...
- 浅谈RxJava与2.0的新特性
简介 说起 RxJava ,相信诸多 Android 开发者都不会陌生.作为一个知名的响应式编程库,从前年开始逐渐变得火热,从小众到被众多 Android 开发者们广泛引入与流传,其在 GitHub ...
- Android Retrofit使用教程(三):Retrofit与RxJava初相逢
上一篇文章讲述了Retrofit的基本使用,包括GET,POST等请求.今天的文章中Retrofit要与RxJava配合使用. 了解RxJava RxJava有种种好处,我不在这里一一讲述.这里我只给 ...
- RxJava的初步认识
希望,记录:RxJava的组成与流程 第一次接触RxJava,它把数据生成与数据使用相分离模型 说明: Observable是数据生成器,数据可以通过各种变换(transform)来整理成需要的格 ...
- rxjava获取异步请求的结果_我为什么不再推荐用 RxJava
点击"开发者技术前线",选择"星标?" 13:21 在看|星标|留言, 真爱 作者: W_BinaryTreehttps://juejin.im/post/5 ...
- android ------- 开发者的 RxJava 详解
在正文开始之前的最后,放上 GitHub 链接和引入依赖的 gradle 代码: Github: https://github.com/ReactiveX/RxJava https://githu ...
- 深入浅出RxJava(三:响应式的好处)
在第一篇中,我介绍了RxJava的基础知识.第二篇中,我向你展示了操作符的强大.但是你可能仍然没被说服.这篇里面,我讲向你展示RxJava的其他的一些好处,相信这篇足够让你去使用Rxjava. 错误处 ...
- android RxJava(RxAndroid)的简单使用
今天,简单讲讲android里如何使用RxJava(RxAndroid). Android框架系列: 一.android EventBus的简单使用 二.android Glide简单使用 三.and ...
最新文章
- 域名解析可以带端口吗_带互感器的三相电表接线,S2可以不接地吗?ABC相序可以错吗?...
- erlang精要(30)-卫语句
- 全选按钮的使用。winfrom程序中,对全选按钮的理解,欢迎拍砖!
- Confluence 6 考虑使用自定义 CSS
- 通过制作数字桌面游戏和Web应用程序学习JavaScript
- 一步一步学Remoting系列文章
- 在CentOS上安装NodeJS_v14.x
- 【报告分享】巨量引擎2019娱乐算数白皮书.pdf(附下载链接)
- 正态分布下含绝对值的期望求解 -- 待验证
- 数据库管理工具 Navicat使用教程:导航窗格提示和技巧 - 管理连接
- angular-devextreme treeview 学习笔记
- 11月全国程序员平均工资最新出炉,网友:我丢了同行的脸
- Druid监控页面配置与使用
- SRM采购框架协议阶梯计价方法
- 接口测试 Pytest断言处理_告警断言
- Oracle触发器(当A表新增/修改/删除时,同步数据到B表)
- 无人驾驶能解决什么问题?
- 三分钟了解如何准备简历面试
- Chrome浏览器查看、找回保存的网站账户密码
- python处理日值气象数据