在项目开发中,都会涉及到网络的请求,okhttp的话是谷歌官方推荐的一个网络请求框架,支持异步GET请求、异步POST请求、异步上传文件、异步下载文件等多种操作, 这里主要说的是okhttp json格式请求数据情况下的异步POST请求、okhttp的https认证以及图片上传。
引入依赖库:
compile files('libs/okhttp-3.7.0.jar')
compile files('libs/okio-1.9.0.jar')
添加网络权限:
<uses-permission android:name="android.permission.INTERNET"/>
okhttp的https认证:
下面写的https认证采用的是单项认证,不是双向认证;
/**
* 以下为https的认证,这里采用的是https的单项认证 okhttp不验证直接通过通过所有的https连接
*
* @author miao
*/
private static class TrustAllCerts implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers()
return new X509Certificate[0];
}
}
@SuppressWarnings("unused")
private static class TrustAllHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
private static SSLSocketFactory createSSLSocketFactory() {
SSLSocketFactory ssfFactory = null;
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom());
ssfFactory = sc.getSocketFactory();
} catch (Exception e) {
}
return ssfFactory;
}
上面这些就是https的单项认证,在调用okhttp请求网络的时候进行设置认证就可以了;
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
/**
* 请求网络 https认证
* @param context 上下文
* @param jsonData json字符串数据
* @param doRequestUrl 请求链接
*/
public static void requestTask(Context context,String jsonData,String doRequestUrl){
if(context==null){
return;
}
OkHttpClient client = new OkHttpClient.Builder().sslSocketFactory(createSSLSocketFactory()).hostnameVerifier(new TrustAllHostnameVerifier())// https认证
.connectTimeout(30000, TimeUnit.MILLISECONDS).readTimeout(35000, TimeUnit.MILLISECONDS)// 设置连接时间和读取时间
.build();// 设置缓存
RequestBody body = RequestBody.create(JSON, jsonData);
Request request = new Request.Builder().url(doRequestUrl).post(body).build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//失败回调 回调是在子线程中,可使用Handler、post、activity.runOnUiThread()等方式在主线程中更新ui
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//成功回调 可使用Handler、post、activity.runOnUiThread()等方式在主线程中更新ui
//获取返回byte数组
byte[] bytes1 = response.body().bytes();
String resultData = new String(bytes1);
}
});
}
上面的所谓的json格式的请求数据就是类似于下面的数据格式:
{"data":{"address":"广州","id":1,"name":"xiaoluo"}}
okhttp图片提交请求:
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
/**
* okhttp提交图片请求
* @param mContext 上下文
* @param imageUrl 图片本地地址
* @param requestUrl 请求链接
*/
public static void doPicTaskInfo(Context mContext, String imageUrl,String requestUrl){
if(mContext==null){
return;
}
//设置连接,读写时间
OkHttpClient client = new OkHttpClient.Builder().connectTimeout(25000, TimeUnit.MILLISECONDS).writeTimeout(30000, TimeUnit.MILLISECONDS)
.readTimeout(30000, TimeUnit.MILLISECONDS).build();
final File f = new File(imageUrl);
MultipartBody.Builder mbody = new MultipartBody.Builder().setType(MultipartBody.FORM);
if (f != null) {
mbody.addFormDataPart("image", f.getName(), RequestBody.create(MEDIA_TYPE_PNG, f));
}
MultipartBody requestBody = mbody.build();
//构建请求
Request request = new Request.Builder()
.url(requestUrl)//地址
.post(requestBody)//添加请求体
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//失败回调 回调是在子线程中,可使用Handler、post、activity.runOnUiThread()等方式在主线程中更新ui
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//成功回调 可使用Handler、post、activity.runOnUiThread()等方式在主线程中更新ui
//请求成功
byte[] bytes = response.body().bytes();
String result = new String(bytes);
}
});
}