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()。
后面需要注意,代码调试的时候表达式的监视有时候会影响代码的运行。
引以为戒。