网络交互是一个项目中必不可少的部分,各种各样的框架都有,有人用Volley,Android-Asycn-Http,XUtils,OkHttp等,我就选了个OkHttp,用了一年了,去年写了个自己使用的博客记录下来,然后前一阵子删了,因为当时刚用,现在发现当初了解使用的太浅,很多不合理不正确的地方,现在任务少,没事,就来写一篇记录我用的OkHttp。
用到它的地方也不多,就是网络交互get请求和post请求,上传,下载,不啰嗦了,直接上代码,写好OkHttp的类,类名为LoaderManagerOk。
private OkHttpClient client;
private LoaderCallback callback;
private Activity activity;
private boolean isBackOnUiThread;
private Call call;
1.定义回调接口(执行请求后的结果):
public interface LoaderCallback{
void onLoadComplete(String url, JSONObject jsonObject);
void onLoadErr(String url, String err);
}
2.初始化OkHttpClient(设置超时):
//初始化client
private void initClient() {
client = new OkHttpClient();
client.setConnectTimeout(5, TimeUnit.SECONDS);
client.setReadTimeout(10, TimeUnit.SECONDS);
client.setWriteTimeout(10, TimeUnit.SECONDS);
}
3.get请求的方法封装(参数使用Map形式):
public void loaderGet(String url,Map<String,String> map){
String getUrl = url;
StringBuilder sb = new StringBuilder(); //字符串拼接
if(map != null){
for(String str:map.keySet()){
sb.append("?");
sb.append("&" + str + "=" + map.get(str));
}
}
getUrl += sb.toString();
Request request = new Request.Builder()
.url(getUrl)
.build();
loadClient(request, url); //执行请求
}
4.post请求的方法封装(参数使用Map形式):
public void loaderPost(String url, Map<String, String> map,int code) {
//添加参数,方式1
FormEncodingBuilder formBody = new FormEncodingBuilder();
for (String str : map.keySet()) {
formBody.add(str, map.get(str));
}
RequestBody requestBody = formBody.build();
/**
*
方式2,分块请求
MultipartBuilder multipartBuilder = new MultipartBuilder();
multipartBuilder.type(MultipartBuilder.FORM);
for(String str:map.keySet()){
multipartBuilder.addFormDataPart(str, map.get(str));
}
RequestBody requestBody = multipartBuilder.build();
*
*/
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
loadClient(request, url,code); //执行请求
}
5.执行请求的封装(采用的异步,如果需要采用同步请求,可将call.enqueue(new Callback())方法改为call.execute(),使用示例:Response response = call.execute();这个response就是请求的返回结果):
private void loadClient(final Request request,final String url){
call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
//请求失败
clientFailure(url);
}
@Override
public void onResponse(final Response response) throws IOException {
//请求成功
try {
if (response.code() == 200) {
//response.body().string()即服务器返回给我们的结果
JSONObject jsonObject = new JSONObject(response.body().string());
clientSucceed(url, jsonObject);
} else {
clientFailure(url, "网络数据请求失败");
}
} catch (JSONException e) {
clientFailure(url, "网络数据请求失败");
e.printStackTrace();
}
}
});
}
注意:如果是同步请求,需要新启线程执行网络请求;如果是异步不需要新启线程,因为OkHttp内部已使用了ThreadPool执行。两者的返回结果都是在子线程中执行,所以更新UI需要自己做操作了。建议(自己也是用的这种方式)封装的该类名为LoaderManagerOk,那么构造方法就用:
public LoaderManagerOk(LoaderCallback callbackOk,Activity activity,boolean isBackOnUiThread){
this.callback = callbackOk;
this.activity = activity;
this.isBackOnUiThread= isBackOnUiThread; //true代表直接返回结果到UI线程(这样就不需要使用Handler等方法操作UI),false代表返回到子线程中
initClient();
}
将Activity传过来,然后再执行下面的第6步和第7步。
6.请求失败的方法封装:
private void clientFailure(final String url){
if(!isBackOnUiThread){
callback.onLoadErr(url,"网络未链接,请检查网络状态后重试");
}else {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
callback.onLoadErr(url, "网络未链接,请检查网络状态后重试");
}
});
}
}
public void clientSucceed(final String url,final JSONObject jsonObject){
if(!isBackOnUiThread){
callback.onLoadComplete(url, jsonObject);
}else {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
callback.onLoadComplete(url, jsonObject);
}
});
}
}
8.取消连接:
public void cancelCall(){
if(call != null){
call.cancel();
}
}
网络交互get和post请求代码就是这样,其中有些不完善,可以根据自己的想法进行更改,大概就是这样,至于使用OkHttp进行上传和下载会在下次博客进行补上。
另外,OkHttp官方文档并不建议我们创建多个OkHttpClient,因此建议全局使用一个。