在欲望的城市里,你就是我最后的信仰。
目录
前言
关于RXJava的基本使用,请参考 文章android--RXJava详细使用篇-CSDN博客
下面我们讲一下RXJava在android中的相对比较高级的用法
一,方法封装
在上篇文章中,我们有个加载图片的案例:
Observable.just(IMGPATH)//发送图片地址
.map(new Function<String, Bitmap>() {
@Override
public Bitmap apply(String s) throws Exception {
URL url = new URL(IMGPATH);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnecti
httpURLConnection.setConnectTimeout(5000);
int responseCode = httpURLConnection.getResponseCode(); // 才开始 request
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = httpURLConnection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
}
return null;
}
})
.map(new Function<Bitmap, Bitmap>() {
@Override
public Bitmap apply(Bitmap bitmap) throws Exception {
System.out.println("下载图片");
return bitmap;
}
})
.subscribeOn(Schedulers.io())//上面是异步
.observeOn(AndroidSchedulers.mainThread())//下面是主线程
.subscribe(new Observer<Bitmap>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Bitmap bitmap) {
img.setImageBitmap(bitmap);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
但是有些操作,比如线程切换,我们每次都要写重复的代码,这时我们就可以把他们封装起来:
//创建Observable
Observable.just(IMGPATH)//发送图片地址
.map(new Function<String, Bitmap>() {
@Override
public Bitmap apply(String s) throws Exception {
URL url = new URL(IMGPATH);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(5000);
int responseCode = httpURLConnection.getResponseCode(); // 才开始 request
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = httpURLConnection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
}
return null;
}
})
.map(new Function<Bitmap, Bitmap>() {
@Override
public Bitmap apply(Bitmap bitmap) throws Exception {
System.out.println("下载图片");
return bitmap;
}
})
.compose(method())//公共的方法提取
.subscribe(new Observer<Bitmap>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Bitmap bitmap) {
img.setImageBitmap(bitmap);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
public static <T> ObservableTransformer<T,T> method(){
return new ObservableTransformer<T, T>() {
@Override
public ObservableSource<T> apply(Observable<T> upstream) {
return upstream.subscribeOn(Schedulers.io()) // 给上面代码分配异步线程
.observeOn(AndroidSchedulers.mainThread())// 给下面代码分配主线程
.map(new Function<T, T>() {
@Override
public 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;
@Override
public 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;
@Override
public 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>>() {
@Override
public ObservableSource<ProjectBean> apply(Object o) throws Exception {
return api.getProject(); // 主数据
}
})
.flatMap(new Function<ProjectBean, ObservableSource<ProjectBean.DataBean>>() {
@Override
public ObservableSource<ProjectBean.DataBean> apply(ProjectBean projectBean) throws Exception {
return Observable.fromIterable(projectBean.getData()); //可以分发多次
}
})
.flatMap(new Function<ProjectBean.DataBean, ObservableSource<ProjectItem>>() {
@Override
public ObservableSource<ProjectItem> apply(ProjectBean.DataBean dataBean) throws Exception {
return api.getProjectItem(1, dataBean.getId());
}
})
.observeOn(AndroidSchedulers.mainThread()) // 切换 主线程
.subscribe(new Consumer<ProjectItem>() {
@Override
public void accept(ProjectItem projectItem) throws Exception {
System.out.println("更新 ui")
}
});
}
通过使用flatMap就避免了多层嵌套的情况,flatMap和throttleFirst上篇文章已经讲过了,这里就不再多说了,主要是使用。