在众多的网络请求中,okhttp算口碑很不错的,再加上和Retrofit的结合,那用起来简直就是太方便了。
Retrofit的优势:
导入依赖库:
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.okhttp3:okhttp:3.9.1'
compile 'com.squareup.okio:okio:1.13.0'
compile 'com.google.code.gson:gson:2.8.2'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:converter-scalars:2.3.0'
1.接口服务包装类RetrofitWrapper.java,负责网络请求的相关配置:
public class RetrofitWrapper {
private static RetrofitWrapper instance;
private Retrofit retrofit;
private RetrofitWrapper() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
/**
*设置缓存
*/
final File chachefile = new File("CacheFilePath");
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 (!AppUtils.isNetworkReachable(AppAplication.getContext())) {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
}
Response response = chain.proceed(request);
if (AppUtils.isNetworkReachable(AppAplication.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);
/**
*公共参数
*/
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);
/**
* 设置请求头
*/
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);
/**
* Log信息拦截器
*/
//compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
if (BuildConfig.DEBUG) {
//log信息拦截器
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
//设置Debug Log模式
builder.addInterceptor(httpLoggingInterceptor);
}
/**
* 设置cookie
*/
//compile 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1'
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
builder.cookieJar(new JavaNetCookieJar(cookieManager));
/**
* 设置超时和重连
*/
//设置超时
builder.connectTimeout(15, TimeUnit.SECONDS);
builder.readTimeout(20, TimeUnit.SECONDS);
builder.writeTimeout(20, TimeUnit.SECONDS);
//错误重连
builder.retryOnConnectionFailure(true);
//以上设置结束,才能build(),不然设置白搭 (上面的设置都可以省略)
OkHttpClient okHttpClient = builder.build();
retrofit = new Retrofit.Builder()
.baseUrl(ApiUtils.BASE_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create()) // 解析方法
.client(okHttpClient)
.build();
}
/**
* 单例模式
*
* @return
*/
public static RetrofitWrapper getInstance() {
if (instance == null) {
synchronized (RetrofitWrapper.class) {
if (instance == null) {
instance = new RetrofitWrapper();
}
}
}
return instance;
}
public T create(final Class service) {
return retrofit.create(service);
}
}
其中:设置缓存、公共参数、设置请求头、Log信息拦截器、设置cookie、设置超时和重连如果不需要都可以省略
2.接口调用类RetrofitModel.java,负责具体调用的接口
/**
* 接口调用类
* @author WangBin
* @date 2018年1月15日 下午5:29:56
* @Description: TODO
* @version V1.0
*/
public class RetrofitModel {
private static RetrofitModel retrofitModel;
private RetrofitService retrofitService;
public static RetrofitModel getInstance() {
if (retrofitModel == null) {
retrofitModel = new RetrofitModel();
}
return retrofitModel;
}
private RetrofitModel() {
retrofitService = RetrofitWrapper.getInstance().create(RetrofitService.class);
}
/**
* 获取用户信息(异步)
* @param username
* @param callback
*/
public void getUser(String username, HttpCallback callback) {
Call call = retrofitService.getUser(username);
RetrofitRequest request = new RetrofitRequest(call);
request.requestAsync(callback);
}
/**
* 获取用户信息(同步)
* @param username
* @return
*/
public User getUserSync(String username){
Call call = retrofitService.getUser(username);
RetrofitRequest request = new RetrofitRequest(call);
return request.requestSync();
}
}
3.接口api类RetrofitService.java
public interface RetrofitService {
@GET("users/{username}")
Call getUser(@Path("username") String username);
@POST("android/login.in")
Call login(@Query("loginName") String loginName, @Query("password") String password);
/**
@Path:所有在网址中的参数(URL的问号前面),如:
http://102.10.10.132/api/Accounts/{accountId}
@Query:URL问号后面的参数,如:
http://102.10.10.132/api/Comments?access_token={access_token}
@QueryMap:相当于多个@Query
@Field:用于POST请求,提交单个数据
@Body:相当于多个@Field,以对象的形式提交
**/
}
4.具体的网络请求类RetrofitRequest.java
public class RetrofitRequest {
private Call mCall;
public RetrofitRequest(Call call) {
mCall = call;
}
/**
* 异步请求
*
* @param callback
*/
public void requestAsync(final HttpCallback callback) {
mCall.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
String path = mCall.request().url().toString();
if (response.isSuccessful() && response.errorBody() == null) {
callback.onSuccess((T) response.body(), path);
} else {
callback.onFailure(response.errorBody().toString());
}
}
@Override
public void onFailure(Call call, Throwable t) {
callback.onFailure(t.getMessage());
}
});
}
/**
* 同步请求
*
* @return
*/
public T requestSync() {
Response response = null;
try {
response = mCall.execute();
} catch (IOException e) {
e.printStackTrace();
}
return (T) response.body();
}
5.请求回调类HttpCallback.java
public abstract class HttpCallback {
public Class> clazz;
public HttpCallback() {
Type superclass = getClass().getGenericSuperclass();
ParameterizedType parameterizedType = null;
if (superclass instanceof ParameterizedType) {// 参数化的泛型
parameterizedType = (ParameterizedType) superclass;
Type[] typeArray = parameterizedType.getActualTypeArguments();
if (typeArray != null && typeArray.length > 0) {
clazz = (Class>) typeArray[0];
}
}
}
public abstract void onSuccess(T response, String path);
public abstract void onFailure(String errorResponse);
}
示例中使用到的Apiutils.BASE_URL为:public static final String BASE_URL = "https://api.github.com/";
源码下载