第一次写这种技术性的微博,请各位指点哈!RxAndroid和Retrofit都算是当下非常流行的Android开发框架,这两个框架光是单独使用就已经爽歪歪了,
那么将RxAndroid和Retrofit结合起来,又会有怎样的效果呢?
1.RxJava优势
1.RxJava作为Android开发者的新宠已经有很长一段时间了,用过RxJava的人,都觉得这个东西简单好用,没用过的小伙伴第一次看到RxJava的代码时可能会觉得这个东西非常繁琐,总的,RxJava的优势就是“异步”处理的更好 比以前的asynctask(会出现内存泄露)。
RxJava的GitHub地址
2.给大家几个学习的参考教程吧 :
Android RxJava使用介绍 说的很详细,里面有四篇帖子哈.
深入浅出RxJava 这四篇帖子需要一点点的lambda语法哈 但是说的也很不错 ,推荐。
2.Retrofit的简单介绍
Retrofit是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于OkHttp实现的,OkHttp现在已经得到Google官方认可的网络请求。
retrofit的github地址
3. RxAndroid+Retrofit(网络访问+文件上传)
需要添加的库
compile 'io.reactivex:rxandroid:1.2.1'
compile 'io.reactivex:rxjava:1.2.4'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.alibaba:fastjson:1.1.55.android'
compile 'com.squareup.retrofit2:converter-scalars:2.0.0-beta4'
//打印网络日志的
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
//retrofit2适应rxjava
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
1.初始化OkHttpClient
这里主要是初始化OkHttp客户端,配置一些基本分参数。
private OkHttpClient getBaseOKhttpClient() {
OkHttpClient.Builder builder = new OkHttpClient().newBuilder()
.connectTimeout(20, TimeUnit.SECONDS)//设置超时时间
.readTimeout(2000, TimeUnit.MILLISECONDS)//设置读取超时时间
.writeTimeout(2000, TimeUnit.MILLISECONDS);//设置写入超时时间
int cacheSize = 10 * 1024 * 1024; // 10 MiB//缓存大小,可酌情修改
Cache cache = new Cache(BaseApplication.getInstance().getExternalCacheDir(), cacheSize);
builder.cache(cache);//设置缓存目录
builder.retryOnConnectionFailure(true);// 方法为设置出现错误进行重新连接。
builder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));//网络日志打印
OkHttpClient mOkHttpClient = builder.build();//构建客户端
return mOkHttpClient;
2.Retrofit的实体
得到Retrofit的实体,处理配置基本信息
private Retrofit getRetrofitInstance() {
if (retrofit == null)
//初始化Retrofit
builder = new Retrofit.Builder();
retrofit = builder
.baseUrl(BASE_URL)//基本网址前缀,不可为空,或者是不配置.
//增加retrofit对rxjava的支持 关联起来 必不可少的一步
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//增加返回值为String的支持 我这里直接让他作为字符串返回就行了
// 可以添加其他的格式化工具,例如gson的 库 compile //'com.squareup.retrofit2:converter-gson:2.1.0' 配置方法
//addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.client(getBaseOKhttpClient()) //添加自定义的okhttp客户端
.build();
return retrofit;
}
3.retrofit的请求类型:
首先定义请求接口,即程序中都需要什么请求操作 POST GET Multipart(文件上传)
interface HttpService {
// 不然报错 @FieldMap parameters can only be used with form encoding. (parameter #2)
@FormUrlEncoded
@POST
Observable<String> POST(@Url String url, @FieldMap Map<String, Object> parms);
@GET
Observable<String> GET(@Url String url, @QueryMap Map<String, Object> map);
@Multipart
@POST
Observable<String> UploadMultFile(@Url String ulr, @PartMap Map<String, ProgressRequestBody> parms);
}
4.执行网络请求
/**
* 开始执行网络请求
*
* @param url 网址
* @param parms 请求参数
* @param subscriber 观察者
*/
protected void startEnqueue(String url, Map parms, final Subscriber subscriber) {
switch (callType) {
case GET:
request = ServiceType().GET(url, parms);
break;
case POST:
request = ServiceType().POST(url, parms);
break;
case UPloadMultFile:
Map requestBodys = new HashMap();
Boolean hasFalse = false;
if (null != parms) {
int i = 0;
for (Map.Entry entry : parms.entrySet()) {
File file = new File(entry.getValue() + "");
if (file.exists()) {
//requestBodys.put("file" + i + "\"; filename=\"" + file.getName(), RequestBody.create(MediaType.parse("image/png"), file));
logError(Uploadlistener + "");
ProgressRequestBody fileBody = new ProgressRequestBody(file, Uploadlistener);
requestBodys.put("file" + i + "\"; filename=\"" + file.getName(), fileBody);
i++;
} else {
hasFalse = true;
}
}
}
if (hasFalse) logError("部分文件目录异常,请稍后重试!");
request = ServiceType().UploadMultFile(url, requestBodys);
break;
}
// httpcallback.setRetryParms(url, request, parms, callType);
subscriion = request.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(result -> {
//网络访问成功
Dto dto = JSON.parseObject(result.toString(), Dto.class);
if (!subscriber.isUnsubscribed())
subscriber.onNext(dto);
},
e -> {
//网络访问出错
subscriber.onError(e);
},
() -> {
//网络访问结束
subscriion.unsubscribe();//取消注册
subscriber.onCompleted();
}
);
}
5.请求方法的简单封装
/**
* post请求
*
* @param url
* @param parms
* @param subscriber 观察者
*/
public void Post(@NonNull String url, @Nullable Map parms, @Nullable final Subscriber subscriber) {
parms = Readey(parms, subscriber);
callType = CallType.POST;
startEnqueue(url, parms, subscriber);
}
6.基本api的封装,方便添加一些基本信息和调用一些公用的方法
abstract class BaseApi {
// static {
// System.loadLibrary("gongpan");
// }
protected static final String getUrl(String actition) {
return actition + "?";
}
protected static final Map getMap() {
Map maps = new HashMap();
/**
* temp:签名字段【app通过time和ieme通过native方法生成】
ieme:设备号
time:当前时间【生成方式:new Date().getTime()+""】
*/
return maps;
}
//xRetrofit是我写的一个网络请求的类 里面主要包括了 得到Retrofit的实体 初始化okhttp客户端,几种请求方法的基本封装
/****
* 懒汉模式
*/
public static xRetrofit init() {
if (null == instance)
synchronized (xRetrofit.class) {
if (null == instance)
instance = new xRetrofit();
}
return instance;
}
protected static void post(String url, Map maps, Subscriber subscriber) {
xRetrofit xretrofit = xRetrofit.init();//看上面代码 获取到xRetrofit这个类 方便调用里面的方法
xretrofit.Post(url, maps, subscriber);//执行xRetrofit中公共post请求
}
protected static void get(String url, Map maps, Subscriber subscriber) {
xRetrofit xretrofit = xRetrofit.init();
xretrofit.GET(url, maps, subscriber);//执行xRetrofit中公共GET请求
}
protected static void UploadMultFile(String url, Map maps, ProgressRequestBody.UploadCallbacks Uploadlistener, Subscriber subscriber) {
xRetrofit xretrofit = xRetrofit.init();
xretrofit.UploadMultFile(url, maps, Uploadlistener, subscriber);
//执行xRetrofit中公共UploadMultFile请求
}
}
7.api的class写法:统一写,很方便调用,代码也很间接 继承baseapi:
//这里调用的是一个聚合数据的搞笑短语的集合
public class HomeApi extends BaseApi {
public static void getTopic_list(Subscriber subscriber) {
String url = getUrl("joke/content/list.from");
Map maps = getMap();
maps.put("sort", "desc");
maps.put("pagesize", "20");
maps.put("time", "1418816972");
maps.put("key", "df2e47d904c41e62071247bd7399da23");
post(url, maps, subscriber);//执行的post请求
}
//文件上传的举例
//Uploadlistener上传进度的监听
public static void FileUpload(List paths, ProgressRequestBody.UploadCallbacks Uploadlistener, Subscriber subscriber) {
String url = getUrlAppend(“app/AppFileUpload”);
Map
}
8.简单的封装了一下Subscriber,方便统一处理一下返回信息(错误处理,网络弹窗等等)
public abstract class BaseSubscriber extends Subscriber<Dto> {
@Override
public void onCompleted() {
logError("请求结束");
}
@Override
public void onError(Throwable t) {
if (t.toString().contains("SocketTimeoutException")) {
logError("亲,网络连接超时了,重试?");
return;
}
if (t.toString().contains("ConnectException")) {
logError("亲,无法连接到服务器,重试?");
return;
}
}
@Override
public void onNext(Dto dto) {
}
public static void logError(Object obj) {
Log.e("Xiang", obj.toString());
}
}
9.在页面事件中api的调用,执行网络请求
//调用网络访问
HomeApi.getTopic_list(new BaseSubscriber() {
@Override
public void onNext(Dto dto) {
super.onNext(dto);
}
});
好了 ,先写到这里,空闲时间我会不断的完善。有啥bug欢迎各位前辈指出,谢谢
项目demo的github地址