一.前言
越来越多的人使用okhttp作为自己的网络访问框架,okhttp与Reftrofit的结合也是很多人喜欢用的.本文就OkHttp与Reftrofit2与RxJava的结合使用的小demo介绍这三者的联合使用.
二.okhttp
1.引入库文件
compile 'com.squareup.okhttp:okhttp:2.4.0'
compile 'com.squareup.okio:okio:1.5.0'
注意:okhttp内部依赖okio,别忘了引入.
2.get请求
其实单纯使用okhttp的网络请求和我们常用的volley等还是挺像的.没什么难度.
// 使用ohhttp访问网络
public void get(String url, Callback callback) {
//创建okHttpClient对象
OkHttpClient mOkHttpClient = new OkHttpClient();
//创建一个Request
Request request = new Request.Builder()
.url(url)
.get()
.build();
//new call
Call call = mOkHttpClient.newCall(request);
//请求加入调度
call.enqueue(callback);
}
调用
get("http://apis.baidu.com/heweather/pro/attractions", new Callback() {
@Override
public void onFailure(Request request, IOException e) {
CustomToast.showToast(e.toString());
}
@Override
public void onResponse(Response response) throws IOException {
CustomToast.showToast(response.body().string());
}
});
3.post请求
public void post(String url,Callback callback){
//创建okHttpClient对象
OkHttpClient mOkHttpClient = new OkHttpClient();
FormEncodingBuilder builder = new FormEncodingBuilder();
builder.add("username","king");
Request request = new Request.Builder()
.url(url)
.post(builder.build())
.build();
mOkHttpClient.newCall(request).enqueue(callback);
}
调用
post("https://github.com/hongyangAndroid", new Callback() {
@Override
public void onFailure(Request request, IOException e) {a
CustomToast.showToast(e.toString());
}
@Override
public void onResponse(Response response) throws IOException {
CustomToast.showToast(response.body().string());
}
});
4.其他
1.这里只介绍okhttp的基础使用,像文件上传下载和对其二次封装就不过多的说了.具体可以看下这篇文章
http://blog.csdn.net/lmj623565791/article/details/47911083
2.这里request请求用了Request.Builder这样一个方法.这其实就是一个建造者模式的应用,我们在使用alert的时候也见过这样的代码
AlertDialog.Builder builder=new AlertDialog.Builder(this);
具体可以看我写的另一篇博客
android常用的设计模式总结
大家翻一下源码很容易看明白的,核心代码就这一点
public final class Request {
private Request(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.headers = builder.headers.build();
this.body = builder.body;
this.tag = builder.tag != null ? builder.tag : this;
}
public Request build() {
if (url == null) throw new IllegalStateException("url == null");
return new Request(this);
}
}
二.reftrofit2
1.介绍
你可以把reftrofit2理解为是一个基于okhttp的网络访问工具类.
和我们常用的工具类不同的是,Retrofit的解耦更彻底:例如通过注解来配置请求参数,根据需求来选择使用不同的CallAdapter(请求适配器,如:RxJava,Java8, Guava)、Converter(反序列化工具,如json, protobuff, xml, moshi)等。
2.基本使用
(1)引入库文件
//retrofit jar
compile 'com.squareup.retrofit2:retrofit:2.0.2'
//反序列化json工具
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
(2)get请求
先定义一个接口
public interface APIService {
@GET("weather")
Call<Weather> loadeather(@Query("cityname") String cityname,@Query("key") String apiKey);
}
在这里loadeather()方法就是就被标记成了get方法,请求的地址就baseurl+wather.请求参数为cityname和key
看一下调用
Retrofit retrofit = new Retrofit.Builder().baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
APIService service = retrofit.create(APIService.class);
service.loadeather("杭州", apiKey).enqueue(new Callback<Weather>() {
@Override
public void onResponse(Response<Weather> response, Retrofit retrofit) {
if (response.body() != null) {
Weather weather = response.body();
if (weather.getResult() != null) {
//xxx
} else {
tv.setText(weather.getReason());
}
} else {
tv.setText("onResponse: body==null");
}
}
@Override
public void onFailure(Throwable t) {
tv.setText(t.toString());
}
});
这里
.addConverterFactory(GsonConverterFactory.create())
这句话就是把返回结果的json转换成了对象
(3)post请求
同样先定义一个接口
public interface APIUserService {
@FormUrlEncoded
@POST("Login")
Call<UserInfo> login(
@Field("userName") String userName,
@Field("password") String password,
@Field("clubId") int clubId,
@Field("leagueId") int leagueId
);
}
@FormUrlEncoded代表 表单的方式传递键值对
发送的请求是键值对的形式.
不过我们经常发送的请求是json类型的,怎么发送这样的请求呢?
public interface APIUserService {
@POST("Login")
@Headers({"Content-Type: application/json","Accept: application/json"})//需要添加头
Call<UserInfo> login(@Body RequestBody body);
}
发送post请求
String url = "http://106.75.xx.xx:8080/Api/Front/";
Retrofit retrofit = new Retrofit.Builder().baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
APIUserService service = retrofit.create(APIUserService.class);
JSONObject result = new JSONObject();
try {
result.put("userName","admin");
result.put("password","xxxx");
result.put("clubId",1);
result.put("leagueId",2);
} catch (JSONException e) {
e.printStackTrace();
}
HashMap map = new HashMap();
RequestBody body = RequestBody.create(MediaType.parse("application/json"), result.toString());
service.login(body).enqueue(new Callback<UserInfo>() {
@Override
public void onResponse(Response<UserInfo> response, Retrofit retrofit) {
if (response!=null) {
UserInfo body = response.body();
tv.setText(body.toString());
}
}
@Override
public void onFailure(Throwable t) {
tv.setText(t.toString());
}
});
设置Interceptor
这个需要简单提一下,很多时候,比如你使用retrofit需要统一的log管理,给每个请求添加统一的header等,这些都应该通过okhttpclient去操作,比如addInterceptor
这里给大家看一个比较全的设置
package com.ethanco.retrofit2_0test;
import java.io.File;
import java.io.IOException;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.util.List;
import java.util.concurrent.TimeUnit;
import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.Headers;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
/**
* Created by king on 2017/3/26.
*/
public class AppClient {
public static Retrofit retrofit = null;
public static Retrofit retrofit() {
if (retrofit == null) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
//设置缓存,代码略
setCache(builder);
// 公共参数,代码略
setComent(builder);
// 设置头,代码略
setHeader(builder);
//Log信息拦截器,代码略
setLog(builder);
//设置cookie,代码略
setCookie(builder);
//设置超时和重连,代码略
setConnect(builder);
//以上设置结束,才能build(),不然设置白搭
OkHttpClient okHttpClient = builder.build();
retrofit = new Retrofit.Builder()
.baseUrl("192.168.1.101")
.client(okHttpClient)
.build();
}
return retrofit;
}
private static void setCookie(OkHttpClient.Builder builder) {
/**
* 设置cookie
*/
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
builder.cookieJar(new CookieJar() {
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
return null;
}
});
}
private static void setHeader(OkHttpClient.Builder builder) {
/**
* 设置头
*/
Interceptor headerInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request orignaRequest = chain.request();
Request request = orignaRequest.newBuilder()
.header("AppType", "TPOS")
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.method(orignaRequest.method(), orignaRequest.body())
.build();
return chain.proceed(request);
}
};
builder.addInterceptor(headerInterceptor);
}
private static void setComent(OkHttpClient.Builder builder) {
/**
* 公共参数
*/
Interceptor addQueryParameterInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request request;
String method = originalRequest.method();
Headers headers = originalRequest.headers();
HttpUrl modifiedUrl = originalRequest.url().newBuilder()
// Provide your custom parameter here
.addQueryParameter("platform", "adnroid")
.addQueryParameter("version", "1.2.0")
.build();
request = originalRequest.newBuilder().url(modifiedUrl).build();
return chain.proceed(request);
}
};
//公共参数
builder.addInterceptor(addQueryParameterInterceptor);
}
private static void setCache(OkHttpClient.Builder builder) {
final File chachefile = new File(BaseApplication.getContext().getExternalCacheDir(), "HttpCache");
final Cache cache = new Cache(chachefile, 1024 * 1024 * 50);//缓存文件
Interceptor cacheInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!NetWorkUtils.isNetworkConnected(BaseApplication.getContext())) {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
}
Response response = chain.proceed(request);
if (NetWorkUtils.isNetworkConnected (BaseApplication.getContext())) {
int maxAge = 0;
// 有网络时 设置缓存超时时间0个小时
response.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
.removeHeader("Pragma")// 清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效
.build();
} else {
//无网络时,设置超时为4周
int maxStale = 60 * 60 * 24 * 28;
response.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.removeHeader("Pragma")
.build();
}
return response;
}
};
builder.cache(cache).addInterceptor(cacheInterceptor);
}
public static void setConnect(OkHttpClient.Builder builder) {
/**
* 设置超时和重连
*/
//设置超时
builder.connectTimeout(15, TimeUnit.SECONDS);
builder.readTimeout(20, TimeUnit.SECONDS);
builder.writeTimeout(20, TimeUnit.SECONDS);
//错误重连
builder.retryOnConnectionFailure(true);
}
public static void setLog(OkHttpClient.Builder builder) {
/**
* log信息拦截器
*/
if (BuildConfig.DEBUG) {
//log信息拦截器
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
//设置Debug Log模式
builder.addInterceptor(httpLoggingInterceptor);
}
}
}