Android系统提供了两种HTTP通信类,HttpURLConnection和HttpClient。但HttpURLConnection太难用,而Google又在Android 6.0删除了HttpClient的相关API,那么有没有更好用的http请求客户端呢,答案是肯定的,那就是OkHttp,大名鼎鼎的Square开发的,你值得拥有。
OkHttp 处理了很多网络疑难杂症:会从很多常用的连接问题中自动恢复。如果您的服务器配置了多个IP地址,当第一个IP连接失败的时候,OkHttp会自动尝试下一个IP。OkHttp还处理了代理服务器问题和SSL握手失败问题。
下面简单说下怎么使用:
1.导包,使用AS的话直接在gradle中进行配置,由于OkHttp依赖OkIO所以想要的Okio也要导入:
compile 'com.squareup.okhttp3:okhttp:3.4.1' compile 'com.squareup.okio:okio:1.9.0'
2.简单的get请求
请求分2种,异步enqueue()和同步execute(),同步请求会阻塞线程,但是异步请求的onResponse工作在子线程中,所以要更新UI需要使用Handler。
onResponse回调的参数是response,一般情况下,比如我们希望获得返回的字符串,可以通过response.body().string()获取;如果希望获得返回的二进制字节数组,则调用response.body().bytes();如果你想拿到返回的inputStream,则调用response.body().byteStream()
OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder().url("http://www.baidu.com").build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { System.out.println("rep >>> " + response.body().string()); } }); 3.简单的post请求3.1 携带参数,提交键值对
okhttp3.FormBody instead of FormEncodingBuilder.(OkHttp3.x,FormEncodingBuilder已被FormBody取代)
OkHttpClient client = new OkHttpClient(); FormBody body = new FormBody.Builder() .add("a","上海市") .add("aa","松江区") .add("aaa","车墩镇") .build(); Request request = new Request.Builder() .url("http://gc.ditu.aliyun.com/geocoding") .post(body) .build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { System.out.println("rep >>> " + response.body().string()); } }); 3.2 提交字符串数据,但不建议发送超过1M的文本信息 public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("\"application/json; charset=utf-8\""); OkHttpClient client = new OkHttpClient(); String json = "{'username':'张三','age':'18','sex':'男'}"; RequestBody body = RequestBody.create(MEDIA_TYPE_JSON,json); Request request = new Request.Builder() .url("http://gc.ditu.aliyun.com/geocoding") .post(body) .build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { System.out.println("rep >>> " + response.body().string()); } });<span style="color:#FF0000;"><span style="background-color: rgb(255, 0, 0);"><span style="background-color: rgb(0, 0, 0);"><span style="background-color: rgb(255, 255, 255);"><span style="color:#FFFFFF;"> 3</span></span></span></span></span> <span style="color:#FF0000;"><span style="background-color: rgb(255, 0, 0);"></span></span>3.3 提交一个文件
public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8"); OkHttpClient client = new OkHttpClient(); File file = new File("README.md"); Request request = new Request.Builder() .url("https://api.github.com/markdown/raw") .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file)) .build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { } }); 4. 通过OkHttpClient设置请求超时时间,缓存,拦截器,代理,SSL,验证等配置 OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .build(); 5. 通过Request设置请求头信息okhttp3添加请求头,需要在Request.Builder()使用.header(String key,String value)或者.addHeader(String key,String value); 使用.header(String key,String value),如果key已经存在,将会移除该key对应的value,然后将新value添加进来,即替换掉原来的value; 使用.addHeader(String key,String value),即使当前的可以已经存在值了,只会添加新value的值,并不会移除/替换原来的值。
Request request = new Request.Builder() .url("https://api.github.com/repos/square/okhttp/issues") .header("User-Agent", "OkHttp Headers.java") .addHeader("Accept", "application/json; q=0.5") .addHeader("Accept", "application/vnd.github.v3+json") .build(); 6. 认证OkHttp会自动重试未验证的请求。当响应是401 Not Authorized时,Authenticator会被要求提供证书。
OkHttpClient client = new OkHttpClient.Builder() .authenticator(new Authenticator() { @Override public Request authenticate(Route route, Response response) throws IOException { String auth = Credentials.basic("username", "password"); return response.request().newBuilder().header("Authorization",auth).build(); } }) .build(); Request request = new Request.Builder() .url("http://www.baidu.com") .build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { } });