关于retrofit2.0的简单使用,请看我的另一篇博客:
Retrofit2使用(非常简洁易懂) - 秦时明月 - 博客频道 - CSDN.NET
http://blog.csdn.net/baidu_31093133/article/details/51759452
接下来让我们使用okhttp3和rxjava对retrofit2进行封装,前方高能,干货预警。
代码下载:
retrofit2+rxjava+okhttp使用demo。 - 下载频道 - CSDN.NET
http://download.csdn.net/detail/baidu_31093133/9696239
导入需要依赖的包:
compile 'com.github.pwittchen:reactivenetwork:0.1.3'
compile "com.squareup.retrofit2:retrofit:2.1.0"
compile "com.squareup.retrofit2:converter-gson:2.1.0"
compile "com.squareup.retrofit2:adapter-rxjava:2.1.0"
compile "com.squareup.retrofit2:converter-scalars:2.1.0"
注意: com.github.pwittchen:reactivenetwork:0.1.3
导入这个包会自动导入它依赖的rxjava包。这个包是用来监听网络状态的。
首先定义一个Httpservice.java的接口文件
在这个接口文件里定义所有retrofit2访问所需的interface接口
例:
Httpservice.java :
public interface HttpService {
//上传图片和描述
@Multipart
@POST("上传的地址")
Observable uploadUserFile(
@Part("fileName") RequestBody description,
@Part("file\"; filename=\"image.png\"")RequestBody img
);
//上传图片和图片描述,图片类型,用户id等其它信息
//如果除了图片外还需要传递其它信息,只需要增加几个@Part就可以了。
@Multipart
@POST("上传的地址")
Observable uploadUserFileAndId(
@Part("describe") String describe,
@Part("type") String type,
@Part("userid") String userid,
@Part("fileName") RequestBody description,
@Part("file\"; filename=\"image.png\"")RequestBody img
);
}
然后我们再定义一个HttpManager.java,用来管理retrofit2对象
HttpManager.java:
public class HttpManager {
//定义基本地址
public static final String HOST = "baseurl";
//设置连接超时的值
private static final int TIMEOUT = 10;
//声明HttpService对象
protected HttpService httpService;
//声明HttpManager对象
private volatile static HttpManager httpManager;
protected HttpManager() {
//新建一个文件用来缓存网络请求
File cacheDirectory = new File(APP.getContext()
.getCacheDir().getAbsolutePath(), "HttpCache");
//实例化一个OkHttpClient.Builder
OkHttpClient.Builder builder = new OkHttpClient.Builder();
//设置连接超时
builder.connectTimeout(TIMEOUT, TimeUnit.SECONDS);
//设置从主机读信息超时
builder.readTimeout(TIMEOUT, TimeUnit.SECONDS);
//设置写信息超时
builder.writeTimeout(TIMEOUT, TimeUnit.SECONDS);
//设置缓存文件
builder.cache(new Cache(cacheDirectory, 10 * 1024 * 1024));
//设置okhttp拦截器,这样做的好处是可以为你的每一个
//retrofit2的网络请求都增加相同的head头信息,而不用每一个请求都写头信息
builder.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder()
.addHeader("Content-Type", "application/json; charset=UTF-8")
.addHeader("Connection", "keep-alive")
.addHeader("Accept", "*/*")
.header("Cache-Control", String.format("public, max-age=%d", 60))
.removeHeader("Pragma")
.build();
return chain.proceed(request);
}
});
Retrofit.Builder rBuilder = new Retrofit.Builder()
.client(builder.build())
//如果网络访问返回的字符串,而不是json数据格式,要使用下面的转换器
.addConverterFactory(ScalarsConverterFactory.create()) //http://blog.csdn.net/u013003052/article/details/50992436
//如果网络访问返回的是json字符串,使用gson转换器
.addConverterFactory(GsonConverterFactory.create())
//此处顺序不能和上面对调,否则不能同时兼容普通字符串和Json格式字符串
//为了支持rxjava,需要添加下面这个把 Retrofit 转成RxJava可用的适配类
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//基本网络地址
.baseUrl(getHost());
httpService = rBuilder.build().create(HttpService.class);
//使用Retrofit.Builder对象可以随时调节retrofit的配置,比下面这种方式要灵活一点
//但是并没有优劣之分
//Retrofit retrofit = new Retrofit.Builder()
// .addConverterFactory(ScalarsConverterFactory.create())
// .addConverterFactory(GsonConverterFactory.create())
// .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
// .baseUrl(HOST)
// .build();
// httpService = retrofit.create(HttpService.class);
}
/**
* 如果有不同的请求HOST可继承此类并Override
*
* @return
*/
protected String getHost() {
return HOST;
}
public HttpService getHttpService() {
return httpService;
}
//使用单例模式
public static HttpManager getInstance() {
if (httpManager == null) {
synchronized (HttpManager.class) {
if (httpManager == null) {
httpManager = new HttpManager();
}
}
}
return httpManager;
}
/**
* 处理http请求——常规
*
* @param pCall
* @param pCallback
*/
public void doHttpRequest(Call pCall, Callback pCallback) {
Call call = pCall;
call.enqueue(pCallback);
}
/**
* 处理http请求——RX
*
* @param pObservable
* @param pSubscriber
*/
public void doHttpRequest(Observable pObservable, Subscriber pSubscriber) {
Observable observable = pObservable
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
observable.subscribe(pSubscriber);
}
/**
* json方式传参
*将json格式的字符串转换成RequestBody
* @param pBody
* @return
*/
public RequestBody getPostBody(String pBody) {
RequestBody body = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), pBody);
return body;
}
}
以上就是封装的两个关键类,接下来就看怎么使用了。
在公司项目里,我们通常把同一个模块下的网络请求方法统一在一个Server文件里,
而不是直接写在activity里
所以我们需要建一个类,比如叫UserInfoServer.java
UserinfoServer.java
//上传头像
//参数是,图片路径,描述,和subscriber。
public static void uploadUserIcon(String imgpath, String des, Subscriber subscriber) {
//构建文件描述的RequestBody
RequestBody description =RequestBody.create(MediaType.parse("multipart/form-data"), des);
//根据图片路径构建图片的RequestBody
File file = new File(imgpath);
RequestBody imgbody = RequestBody.create(MediaType.parse("multipart/form-data"),file);
//获取HttpManager单例,并且调用doHttpRequest方法
//只要我们调用下面这个方法就会自动返回一个
//rxjava的Observable对象,然后这个Observable对象就会执行网络请求并返回给
//参数里的subscriber对象
HttpManager.getInstance().getHttpService().uploadUserFile(description, imgbody)
HttpManager.getInstance().doHttpRequest(HttpManager.getInstance().getHttpService().uploadUserFile(description, imgbody), subscriber);
}
然后我们只需要在activity里这样调用:
一行代码完成retrofit网络请求:
//上传用户图片信息
UserIntegrationServer.uploadUserIcon("图片路径", "图片描述:上传本地头像", new Subscriber() {
@Override
public void onCompleted() {
LogUtil.HDLog("onCompleted 上传头像======");
}
@Override
public void onError(Throwable e) {
LogUtil.HDLog("onError 上传头像======"+e.getMessage());
}
@Override
public void onNext(String s) {
LogUtil.HDLog("onNext 上传头像======" + s);
//上传成功会回调onNext方法,返回值是一个String字符串,这是因为我们在
//HttpService.java里定义的时候Observable uploadUserFile
//定义的返回值是Observable,这个返回值可以根据实际需要修改
}
});
以上就是封装的思路,我一直在用,感觉很不错(^__^)
关于rxjava的使用请参考我的另一篇博客
Rxjava入门 - 秦时明月 - 博客频道 - CSDN.NET
http://blog.csdn.net/baidu_31093133/article/details/51931718