在欲望的城市里,你就是我最后的信仰。
目录
前言
一,方法封装
二,okhttp+retrofit+rxjava 实现网络请求
前言
关于RXJava的基本使用,请参考 文章android--RXJava详细使用篇-CSDN博客
下面我们讲一下RXJava在android中的相对比较高级的用法
一,方法封装
在上篇文章中,我们有个加载图片的案例:
Observable.just(IMGPATH)//发送图片地址.map(new Function<String, Bitmap>() {@Overridepublic Bitmap apply(String s) throws Exception {URL url = new URL(IMGPATH);HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnectihttpURLConnection.setConnectTimeout(5000);int responseCode = httpURLConnection.getResponseCode(); // 才开始 requestif (responseCode == HttpURLConnection.HTTP_OK) {InputStream inputStream = httpURLConnection.getInputStream();Bitmap bitmap = BitmapFactory.decodeStream(inputStream);return bitmap;}return null;}}).map(new Function<Bitmap, Bitmap>() {@Overridepublic Bitmap apply(Bitmap bitmap) throws Exception {System.out.println("下载图片");return bitmap;}}).subscribeOn(Schedulers.io())//上面是异步.observeOn(AndroidSchedulers.mainThread())//下面是主线程.subscribe(new Observer<Bitmap>() {@Overridepublic void onSubscribe(Disposable d) {}@Overridepublic void onNext(Bitmap bitmap) {img.setImageBitmap(bitmap);}@Overridepublic void onError(Throwable e) {}@Overridepublic void onComplete() {}});
但是有些操作,比如线程切换,我们每次都要写重复的代码,这时我们就可以把他们封装起来:
//创建Observable
Observable.just(IMGPATH)//发送图片地址.map(new Function<String, Bitmap>() {@Overridepublic Bitmap apply(String s) throws Exception {URL url = new URL(IMGPATH);HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();httpURLConnection.setConnectTimeout(5000);int responseCode = httpURLConnection.getResponseCode(); // 才开始 requestif (responseCode == HttpURLConnection.HTTP_OK) {InputStream inputStream = httpURLConnection.getInputStream();Bitmap bitmap = BitmapFactory.decodeStream(inputStream);return bitmap;}return null;}}).map(new Function<Bitmap, Bitmap>() {@Overridepublic Bitmap apply(Bitmap bitmap) throws Exception {System.out.println("下载图片");return bitmap;}}).compose(method())//公共的方法提取.subscribe(new Observer<Bitmap>() {@Overridepublic void onSubscribe(Disposable d) {}@Overridepublic void onNext(Bitmap bitmap) {img.setImageBitmap(bitmap);}@Overridepublic void onError(Throwable e) {}@Overridepublic void onComplete() {}});
public static <T> ObservableTransformer<T,T> method(){return new ObservableTransformer<T, T>() {@Overridepublic ObservableSource<T> apply(Observable<T> upstream) {return upstream.subscribeOn(Schedulers.io()) // 给上面代码分配异步线程.observeOn(AndroidSchedulers.mainThread())// 给下面代码分配主线程.map(new Function<T, T>() {@Overridepublic T apply(T t) throws Exception {return t;}}); //也可以把公共的map封装到这里}};
}
二,okhttp+retrofit+rxjava 实现网络请求
这里列举一下两个 请求嵌套的情况下,rxjava是怎么实现的
首先创建两个数据类:
public class ProjectBean {private int errorCode;private String errorMsg;private List<DataBean> data;@Overridepublic String toString() {return "ProjectBean{" +"errorCode=" + errorCode +", errorMsg='" + errorMsg + '\'' +", data=" + data +'}';}public int getErrorCode() {return errorCode;}public void setErrorCode(int errorCode) {this.errorCode = errorCode;}public String getErrorMsg() {return errorMsg;}public void setErrorMsg(String errorMsg) {this.errorMsg = errorMsg;}public List<DataBean> getData() {return data;}public void setData(List<DataBean> data) {this.data = data;}public static class DataBean {private int courseId;private int id;private String name;private int order;private int parentChapterId;private boolean userControlSetTop;private int visible;private List<?> children;@Overridepublic String toString() {return "DataBean{" +"courseId=" + courseId +", id=" + id +", name='" + name + '\'' +", order=" + order +", parentChapterId=" + parentChapterId +", userControlSetTop=" + userControlSetTop +", visible=" + visible +", children=" + children +'}';}public int getCourseId() {return courseId;}public void setCourseId(int courseId) {this.courseId = courseId;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getOrder() {return order;}public void setOrder(int order) {this.order = order;}public int getParentChapterId() {return parentChapterId;}public void setParentChapterId(int parentChapterId) {this.parentChapterId = parentChapterId;}public boolean isUserControlSetTop() {return userControlSetTop;}public void setUserControlSetTop(boolean userControlSetTop) {this.userControlSetTop = userControlSetTop;}public int getVisible() {return visible;}public void setVisible(int visible) {this.visible = visible;}public List<?> getChildren() {return children;}public void setChildren(List<?> children) {this.children = children;}}
}
public class ProjectItem {private DataBean data;private int errorCode;private String errorMsg;public static class DataBean {private int curPage;private int offset;private boolean over;private int pageCount;private int size;private int total;private List<DatasBean> datas;public static class DatasBean {private String apkLink;private String author;private int chapterId;private String chapterName;private boolean collect;private int courseId;private String desc;private String envelopePic;private boolean fresh;private int id;private String link;private String niceDate;private String origin;private String prefix;private String projectLink;private long publishTime;private int superChapterId;private String superChapterName;private String title;private int type;private int userId;private int visible;private int zan;private List<TagsBean> tags;public static class TagsBean {private String name;private String url;}}}
}
然后创建一个Api请求接口
public interface MyApi {// 总数据@GET("project/tree/json")Observable<ProjectBean> getProject(); // 异步线程 耗时操作// Item数据@GET("project/list/{pageIndex}/json") Observable<ProjectItem> getProjectItem(@Path("pageIndex") int pageIndex, @Query("cid") int cid); // 异步线程 耗时操作
}
创建一个工具类,获取Retrofit
public class Util {public static String BASE_URL = "https://www.wanandroid.com/";public static void setBaseUrl(String baseUrl) {BASE_URL = baseUrl;}/*** 根据各种配置创建出Retrofit** @return 返回创建好的Retrofit*/public static Retrofit getOnlineCookieRetrofit() {// OKHttp客户端OkHttpClient.Builder httpBuilder = new OkHttpClient.Builder();// 各种参数配置OkHttpClient okHttpClient = httpBuilder.addNetworkInterceptor(new StethoInterceptor()).readTimeout(10000, TimeUnit.SECONDS).connectTimeout(10000, TimeUnit.SECONDS).writeTimeout(10000, TimeUnit.SECONDS).build();return new Retrofit.Builder().baseUrl(BASE_URL)// TODO 请求用 OKhttp.client(okHttpClient)// TODO 响应RxJava// 添加一个json解析的工具.addConverterFactory(GsonConverterFactory.create(new Gson()))// 添加rxjava处理工具.addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();}
}
最后,使用rxjava解析数据
@SuppressLint("CheckResult")
private void getData() {// 注意:项目分类查询的id,通过此id再去查询(项目列表数据)Button bt_fangdou = findViewById(R.id.fangdou);RxView.clicks(bt_fangdou).throttleFirst(2000, TimeUnit.MILLISECONDS) // 2秒钟之内 响应一次// 切换 异步.observeOn(Schedulers.io()).flatMap(new Function<Object, ObservableSource<ProjectBean>>() {@Overridepublic ObservableSource<ProjectBean> apply(Object o) throws Exception {return api.getProject(); // 主数据}}).flatMap(new Function<ProjectBean, ObservableSource<ProjectBean.DataBean>>() {@Overridepublic ObservableSource<ProjectBean.DataBean> apply(ProjectBean projectBean) throws Exception {return Observable.fromIterable(projectBean.getData()); //可以分发多次}}).flatMap(new Function<ProjectBean.DataBean, ObservableSource<ProjectItem>>() {@Overridepublic ObservableSource<ProjectItem> apply(ProjectBean.DataBean dataBean) throws Exception {return api.getProjectItem(1, dataBean.getId());}}).observeOn(AndroidSchedulers.mainThread()) // 切换 主线程.subscribe(new Consumer<ProjectItem>() {@Overridepublic void accept(ProjectItem projectItem) throws Exception {System.out.println("更新 ui")}});
}
通过使用flatMap就避免了多层嵌套的情况,flatMap和throttleFirst上篇文章已经讲过了,这里就不再多说了,主要是使用。