在欲望的城市里,你就是我最后的信仰。
目录
前言
一,方法封装
二,okhttp+retrofit+rxjava 实现网络请求
关于RXJava的基本使用,请参考 文章android--RXJava详细使用篇-CSDN博客
下面我们讲一下RXJava在android中的相对比较高级的用法
在上篇文章中,我们有个加载图片的案例:
Observable.just(IMGPATH)//发送图片地址
.map(new Function() {
@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() {
@Override
public Bitmap apply(Bitmap bitmap) throws Exception {
System.out.println("下载图片");
return bitmap;
}
})
.subscribeOn(Schedulers.io())//上面是异步
.observeOn(AndroidSchedulers.mainThread())//下面是主线程
.subscribe(new Observer() {
@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() {
@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() {
@Override
public Bitmap apply(Bitmap bitmap) throws Exception {
System.out.println("下载图片");
return bitmap;
}
})
.compose(method())//公共的方法提取
.subscribe(new Observer() {
@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 ObservableTransformer method(){
return new ObservableTransformer() {
@Override
public ObservableSource apply(Observable upstream) {
return upstream.subscribeOn(Schedulers.io()) // 给上面代码分配异步线程
.observeOn(AndroidSchedulers.mainThread())// 给下面代码分配主线程
.map(new Function() {
@Override
public T apply(T t) throws Exception {
return t;
}
}); //也可以把公共的map封装到这里
}
};
}
这里列举一下两个 请求嵌套的情况下,rxjava是怎么实现的
首先创建两个数据类:
public class ProjectBean {
private int errorCode;
private String errorMsg;
private List 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 getData() {
return data;
}
public void setData(List 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 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 tags;
public static class TagsBean {
private String name;
private String url;
}
}
}
}
然后创建一个Api请求接口
public interface MyApi {
// 总数据
@GET("project/tree/json")
Observable getProject(); // 异步线程 耗时操作
// Item数据
@GET("project/list/{pageIndex}/json")
Observable 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
通过使用flatMap就避免了多层嵌套的情况,flatMap和throttleFirst上篇文章已经讲过了,这里就不再多说了,主要是使用。