Okhttp简单辅助类与debug注意事项
先贴代码(代码不全,仅供参考)
import android.os.Handler;
import android.os.Looper;
import android.support.v4.util.ArrayMap;
import com.ztesoft.zsmart.oss.foa.net.http.callback.FOACallBack;
import com.ztesoft.zsmart.oss.foa.net.http.cookie.CookieJarImpl;
import com.ztesoft.zsmart.oss.foa.net.http.cookie.store.CookieStore;
import com.ztesoft.zsmart.oss.foa.net.http.cookie.store.HasCookieStore;
import com.ztesoft.zsmart.oss.foa.net.http.cookie.store.MemoryCookieStore;
import com.ztesoft.zsmart.oss.foa.net.http.exception.Exceptions;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.CookieJar;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* Created by boann on 2016/5/9.
*/
public class OkHttpUtils {
public static final String REQUEST_STRING_KEY_NAME = "mobile_request_attribute"; //json参数的key
public static final int CONNECTION_TIME_OUT_DEFAULT = 20000; //默认连接超时时间
public static final int READ_TIME_OUT_DEFAULT = 60000; //默认读取超时时间
public static final int WRITE_TIME_OUT_DEFAULT = 60000; //默认写超时时间
private static OkHttpUtils mInstance; //单例模式
private OkHttpClient mOkHttpClient; //
private Handler mDelivery; //用于发送结果给UI线程
/**
* 构造函数
* @param okHttpClient
*/
public OkHttpUtils(OkHttpClient okHttpClient) {
if (okHttpClient == null) {
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
//cookie enabled
okHttpClientBuilder.cookieJar(new CookieJarImpl(new MemoryCookieStore()));
okHttpClientBuilder.sslSocketFactory(HttpsUtils.getSslSocketFactory());
okHttpClientBuilder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
mOkHttpClient = okHttpClientBuilder.build();
} else {
mOkHttpClient = okHttpClient;
}
init();
}
/**
* 取得handler
*/
private void init() {
mDelivery = new Handler(Looper.getMainLooper());
}
/**
* 单例模式实现
* @param okHttpClient
* @return
*/
public static OkHttpUtils getInstance(OkHttpClient okHttpClient) {
if (mInstance == null) {
synchronized (OkHttpUtils.class) {
if (mInstance == null) {
mInstance = new OkHttpUtils(okHttpClient);
}
}
}
return mInstance;
}
/**
* 单例模式实现
* @return
*/
public static OkHttpUtils getInstance() {
if (mInstance == null) {
synchronized (OkHttpUtils.class) {
if (mInstance == null) {
mInstance = new OkHttpUtils(null);
}
}
}
return mInstance;
}
/**
* 返回handler
* @return
*/
private Handler getDelivery() {
return mDelivery;
}
/**
* 设置连接,读取,写超时时间
* @return
*/
public OkHttpClient getOkHttpClient() {
mOkHttpClient.newBuilder().connectTimeout(CONNECTION_TIME_OUT_DEFAULT, TimeUnit.MILLISECONDS)
.readTimeout(READ_TIME_OUT_DEFAULT, TimeUnit.MILLISECONDS)
.writeTimeout(READ_TIME_OUT_DEFAULT, TimeUnit.MICROSECONDS)
.build();
return mOkHttpClient;
}
/**
*
* @return
*/
public CookieStore getCookieStore() {
final CookieJar cookieJar = mOkHttpClient.cookieJar();
if (cookieJar == null) {
Exceptions.illegalArgument("you should invoked okHttpClientBuilder.cookieJar() to set a cookieJar.");
}
if (cookieJar instanceof HasCookieStore) {
return ((HasCookieStore) cookieJar).getCookieStore();
} else {
return null;
}
}
/**
* 取消请求
* @param tag
*/
public void cancelTag(Object tag) {
for (Call call : mOkHttpClient.dispatcher().queuedCalls()) {
if (tag.equals(call.request().tag())) {
call.cancel();
}
}
for (Call call : mOkHttpClient.dispatcher().runningCalls()) {
if (tag.equals(call.request().tag())) {
call.cancel();
}
}
}
/**
* 发送失败结果
* @param call
* @param e
* @param callback
*/
private void sendFailResultCallback(final Call call, final Response response, final Exception e, final FOACallBack callback)
{
if (callback == null) return;
mDelivery.post(new Runnable()
{
@Override
public void run()
{
callback.onError(call, response, e);
callback.onAfter();
}
});
}
/**
* 发送成功结果
* @param object
* @param callback
*/
private void sendSuccessResultCallback(final Object object, final FOACallBack callback)
{
if (callback == null) return;
mDelivery.post(new Runnable()
{
@Override
public void run()
{
callback.onResponse(object);
callback.onAfter();
}
});
}
/**
* 打包请求
* @param tag
* @param url
* @param requestString
* @param files
* @return
*/
private static Request getRequest(Object tag, String url, String requestString, ArrayMap<String, ArrayList<String>> files) {
MultipartBody.Builder mBuilder = new MultipartBody.Builder();
mBuilder.setType(MultipartBody.FORM);
mBuilder.addFormDataPart(REQUEST_STRING_KEY_NAME, requestString);
if (files != null) {
int count = files.size();
for (int i = 0; i < count; i++){
ArrayList<String> filePaths = files.valueAt(i);
for (int j = 0; j < filePaths.size(); j++) {
File file = new File(filePaths.get(j));
if (file.exists()) {
mBuilder.addFormDataPart(files.keyAt(i), files.keyAt(i), RequestBody.create(MultipartBody.FORM, new File(filePaths.get(j))));
}
}
}
}
return new Request.Builder()
.tag(tag)
.url(url)
.post(mBuilder.build())
.build();
}
/**
* 执行请求
* @param call
* @param foaCallBack
*/
private void foaCall(Call call, FOACallBack foaCallBack) {
if (foaCallBack == null) {
foaCallBack = DEFAULT_CALLBACK;
}
final FOACallBack finalCallBack = foaCallBack;
foaCallBack.onBefore(call.request());
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
sendFailResultCallback(call, null, e, finalCallBack);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.code() >= 400 && response.code() <= 599) {
try {
sendFailResultCallback(call, response, new RuntimeException(response.body().string()), finalCallBack);
} catch (IOException e) {
e.printStackTrace();
}
return;
}
try {
Object o = finalCallBack.parseNetworkResponse(response);
sendSuccessResultCallback(o, finalCallBack);
} catch (Exception e) {
sendFailResultCallback(call, response, e, finalCallBack);
}
}
});
}
/**
* 异步进行带图片的请求
* @param tag
* @param url
* @param requestString
* @param files
* @param callback
*/
public static void postWithFilesAsyn(Object tag, String url, String requestString, ArrayMap<String, ArrayList<String>> files, FOACallBack callback) {
Call call = getInstance().getOkHttpClient().newCall(getRequest(tag, url, requestString, files));
getInstance().foaCall(call, callback);
}
/**
* 同步进行带图片的请求
* @param tag
* @param url
* @param requestString
* @param files
* @return
*/
public static String postWithFilesSyn(Object tag, String url, String requestString, ArrayMap<String, ArrayList<String>> files) throws Exception{
return OkHttpUtils.getInstance().getOkHttpClient().newCall(getRequest(tag, url, requestString, files)).execute().body().string();
}
/**
* 异步进行不带图片的请求
* @param tag
* @param url
* @param requestString
* @param callback 自定义callback
*/
public static void postAsyn(Object tag, String url, String requestString, FOACallBack callback) {
Call call = getInstance().getOkHttpClient().newCall(getRequest(tag, url, requestString, null));
getInstance().foaCall(call, callback);
}
/**
* 同步进行不带图片的请求
* @param tag
* @param url
* @param requestString
* @return
*/
public static String postSyn(Object tag, String url, String requestString) throws Exception {
return OkHttpUtils.getInstance().getOkHttpClient().newCall(getRequest(tag, url, requestString, null)).execute().body().string();
}
/**
* 默认的callback
*/
public static FOACallBack DEFAULT_CALLBACK = new FOACallBack() {
@Override
public void onBefore(Request request) {
}
@Override
public void onAfter() {
}
@Override
public void inProgress(float progress) {
}
@Override
public Object parseNetworkResponse(Response response) throws Exception {
return null;
}
@Override
public void onError(Call call, Response response, Exception e) {
}
@Override
public void onResponse(Object response) {
}
};
}
接下来是debug时的大坑,困扰了一天
主要代码如下
String requestStr = getRequest(locationBeans).toString();
MultipartBody.Builder mBuilder = new MultipartBody.Builder();
mBuilder.setType(MultipartBody.FORM);
mBuilder.addFormDataPart("mobile_request_attribute", requestStr);
Request request = new Request.Builder()
.url(BasicUtils.getServerUrl(this))
.post(mBuilder.build())
.build();
try {
Response response = OkHttpUtils.getInstance().getOkHttpClient().newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println("Server: " + response.header("Server"));
System.out.println("Date: " + response.header("Date"));
System.out.println("Vary: " + response.headers("Vary"));
System.out.println(response.body().string());
} catch (Exception e) {
e.printStackTrace();
}
运行到response.body().string()一步时抛异常,java.lang.IllegalStateException: closed
查阅各种资料大致意思是The IllegalStateException
arises because the HttpConnection seems to be closed when trying to use it. Could it be because you are calling twice the method response.body()
?
就是说调用response.body().string()的时候数据流已经关闭了,再次调用就是提示已经closed,
检查代码发现,其他的地方并没有调用过response.body().string(),而且是调试的时候有,后来发现是在debug的时候添加了Watchs,就是代码的监视,这里会调用一次response.body().string()。
后面需要注意,代码调试的时候表达式的监视有时候会影响代码的运行。
引以为戒。