Okhttp 使用与debug时留的大坑

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()。

后面需要注意,代码调试的时候表达式的监视有时候会影响代码的运行。

引以为戒。

时间: 2024-10-14 10:15:45

Okhttp 使用与debug时留的大坑的相关文章

IntelliJ IDEA 调试(debug)时非常慢的原因

IntelliJ  IDEA 开发时,发现有时Debug时tomcat启动的非常慢,需要等待超过20分钟,但有时就很快,经查找发现是断点设置问题, 若断点设置在方法名上,debug时就会非常慢, 如图: 一般情况下,方法名不需要的debug的,所以去掉这个断点就OK了.

如果你的eclipse在每次run或debug时都莫名其妙的做一件事

新项目,使用Ant打war包.结果写完了Ant以后,包是打好了,却使eclipse以后每次run或debug时都莫名其妙地自动先执行这个Ant, 让人十分苦恼. 其实,是你的eclipse设置出了问题. 看下面这篇文章: http://developer.51cto.com/art/201205/333497.htm 简单一句话:在你的工程右键>>properties>>builders里面,有不该勾上的东西.

DEBUG : Eclipse&#160;Debug&#160;时出现&#160;Cannot&#160;connect&#160;to&#160;VM&#160;select&#160;failed错误

Eclipse在执行Debug操作时, 出现“Eclipse Debug 时出现 "Cannot connect to VM select failed"”错误, 在网上查找该错误和 ipv4.ipv6 有关,但不知道具体原因. 解决方法如下: 搜索 "eclipse.ini" 文件,一般是在 eclipse 的安装目录, 添加下列控制参数: -Djava.net.preferIPv4Stack=true 即可. 此参数关掉了jvm的ipv6功能,可参考下列文章: 

debug时红点消失

问题描述:debug时红色断点和黄色小箭头不见,而用行代码高亮的形式时. 解决办法:可以用设置 工具 => 选项 => 文本编辑器 => 指示器边距 勾上选项

解决Myeclipse在调试(debug)时无法显示变量值问题

解决Myeclipse在调试(debug)时无法显示变量值问题 突然发现myeclipse在调试时当鼠标放在变量上面时无法显示变量值了 ctrl+shift+D居然提示cannot be resolved 网上查到的最多的方法是 Window->Preferences->Java->Editor->Hovers 将[Variable Values]选择就可以,假设[Combined Hover]已经勾选,取消并勾选[Variable Values] 这样的方法适用的应该不是我的这样

[Intellij idea]解决debug时中文显示方框问题

1. 点击File -> Settings 进入Intellij的设置页面 2. 点击Appearance,选择Override defaults fonts by (not recommended): 下的Name:为Dialog.plain 3. 点击Editor -> Appearance,勾选Use anti-aliased font [Intellij idea]解决debug时中文显示方框问题

Eclipse中debug时鼠标悬停不能查看变量值的问题

问题描述:eclipse在debug模式下,当鼠标移动到某个变量上面时不自动显示该变量对应的值 解决方案:点击eclipse的Window->Preferences->Java->Editor->Hovers, 勾选Variable Values,(如果Combined Hover已经选择了,就取消它), 然后点击Apply,最后点OK.有时不需要勾选Variable Values也能查看变量值,所以勾不勾选多试几下,debug可能就好了. Hovers主要是来用配置当鼠标移动到工

IDEA在debug时修改变量值

例如以下代码: int y1 = 0; anchor.setDy1(y1); 在代码中,这个y1永远是0,但是y1本身是个变量 debug的时候获取到这个属性,并且编辑修改,然后运行时这个值就变成100啦 可知,在debug的时候,取到这个属性,修改值,那么页面上就会使用这个新值 但如果代码是anchor.setDy1(0); 就不可以改变了

汇编语言debug时环境变量问题

今天我在使用汇编语言使用debug这个命令时,打开win+r的cmd,发现输入debug根本不起作用,在网上找了不下20种解决方法,后来久经调试,环境变量改了一大堆.最终...还是木有成功. 后来我想了一下,在浏览器上搜了下debug汇编,读了一片帖子之后才知道win7旗舰版cmd根本不支持debug(一句mmp我想讲给微软听..) http://bbs.fishc.com/thread-58642-1-1.html [伸手党福利]各操作系统环境下,汇编所需软件汇总,从此进入汇编深坑不求人~ w