看了一篇博文,记录一下okHttp的使用。 原文地址: Android OkHttp完全解析 是时候来了解OkHttp了
里边介绍了okHttp基本使用和一些封装,我主要看的是他封装的那部分,OkHttpClientManager.java
1 import android.os.Handler; 2 import android.os.Looper; 3 4 import com.google.gson.Gson; 5 import com.google.gson.internal.$Gson$Types; 6 import com.squareup.okhttp.Call; 7 import com.squareup.okhttp.Callback; 8 import com.squareup.okhttp.FormEncodingBuilder; 9 import com.squareup.okhttp.Headers; 10 import com.squareup.okhttp.MediaType; 11 import com.squareup.okhttp.MultipartBuilder; 12 import com.squareup.okhttp.OkHttpClient; 13 import com.squareup.okhttp.Request; 14 import com.squareup.okhttp.RequestBody; 15 import com.squareup.okhttp.Response; 16 17 import org.json.JSONException; 18 19 import java.io.File; 20 import java.io.FileOutputStream; 21 import java.io.IOException; 22 import java.io.InputStream; 23 import java.lang.reflect.ParameterizedType; 24 import java.lang.reflect.Type; 25 import java.net.CookieManager; 26 import java.net.CookiePolicy; 27 import java.net.FileNameMap; 28 import java.net.URLConnection; 29 import java.util.HashMap; 30 import java.util.Map; 31 import java.util.Set; 32 33 /** 34 * Created by Lee on 2016/2/28. 35 */ 36 public class OkHttpClientManager 37 { 38 private static OkHttpClientManager mInstance; 39 private OkHttpClient mOkHttpClient; 40 private Handler mDelivery; 41 private Gson mGson; 42 43 44 private static final String TAG = "OkHttpClientManager"; 45 46 private OkHttpClientManager() 47 { 48 mOkHttpClient = new OkHttpClient(); 49 //cookie enabled 50 mOkHttpClient.setCookieHandler(new CookieManager(null, CookiePolicy.ACCEPT_ORIGINAL_SERVER)); 51 mDelivery = new Handler(Looper.getMainLooper()); 52 mGson = new Gson(); 53 } 54 55 public static OkHttpClientManager getInstance() 56 { 57 if (mInstance == null) 58 { 59 synchronized (OkHttpClientManager.class) 60 { 61 if (mInstance == null) 62 { 63 mInstance = new OkHttpClientManager(); 64 } 65 } 66 } 67 return mInstance; 68 } 69 70 /** 71 * 同步的Get请求 72 * 73 * @param url 74 * @return Response 75 */ 76 private Response _getAsyn(String url) throws IOException 77 { 78 final Request request = new Request.Builder() 79 .url(url) 80 .build(); 81 Call call = mOkHttpClient.newCall(request); 82 Response execute = call.execute(); 83 return execute; 84 } 85 86 /** 87 * 同步的Get请求 88 * 89 * @param url 90 * @return 字符串 91 */ 92 private String _getAsString(String url) throws IOException 93 { 94 Response execute = _getAsyn(url); 95 return execute.body().string(); 96 } 97 98 99 /** 100 * 异步的get请求 101 * 102 * @param url 103 * @param callback 104 */ 105 private void _getAsyn(String url, final ResultCallback callback) 106 { 107 final Request request = new Request.Builder() 108 .url(url) 109 .build(); 110 deliveryResult(callback, request); 111 } 112 113 114 /** 115 * 同步的Post请求 116 * 117 * @param url 118 * @param params post的参数 119 * @return 120 */ 121 private Response _post(String url, Param... params) throws IOException 122 { 123 Request request = buildPostRequest(url, params); 124 Response response = mOkHttpClient.newCall(request).execute(); 125 return response; 126 } 127 128 129 /** 130 * 同步的Post请求 131 * 132 * @param url 133 * @param params post的参数 134 * @return 字符串 135 */ 136 private String _postAsString(String url, Param... params) throws IOException 137 { 138 Response response = _post(url, params); 139 return response.body().string(); 140 } 141 142 /** 143 * 异步的post请求 144 * 145 * @param url 146 * @param callback 147 * @param params 148 */ 149 private void _postAsyn(String url, final ResultCallback callback, Param... params) 150 { 151 Request request = buildPostRequest(url, params); 152 deliveryResult(callback, request); 153 } 154 155 /** 156 * 异步的post请求 157 * 158 * @param url 159 * @param callback 160 * @param params 161 */ 162 private void _postAsyn(String url, final ResultCallback callback, Map<String, String> params) 163 { 164 Param[] paramsArr = map2Params(params); 165 Request request = buildPostRequest(url, paramsArr); 166 deliveryResult(callback, request); 167 } 168 169 /** 170 * 同步基于post的文件上传 171 * 172 * @param params 173 * @return 174 */ 175 private Response _post(String url, File[] files, String[] fileKeys, Param... params) throws IOException 176 { 177 Request request = buildMultipartFormRequest(url, files, fileKeys, params); 178 return mOkHttpClient.newCall(request).execute(); 179 } 180 181 private Response _post(String url, File file, String fileKey) throws IOException 182 { 183 Request request = buildMultipartFormRequest(url, new File[]{file}, new String[]{fileKey}, null); 184 return mOkHttpClient.newCall(request).execute(); 185 } 186 187 private Response _post(String url, File file, String fileKey, Param... params) throws IOException 188 { 189 Request request = buildMultipartFormRequest(url, new File[]{file}, new String[]{fileKey}, params); 190 return mOkHttpClient.newCall(request).execute(); 191 } 192 193 /** 194 * 异步基于post的文件上传 195 * 196 * @param url 197 * @param callback 198 * @param files 199 * @param fileKeys 200 * @throws IOException 201 */ 202 private void _postAsyn(String url, ResultCallback callback, File[] files, String[] fileKeys, Param... params) throws IOException 203 { 204 Request request = buildMultipartFormRequest(url, files, fileKeys, params); 205 deliveryResult(callback, request); 206 } 207 208 /** 209 * 异步基于post的文件上传,单文件不带参数上传 210 * 211 * @param url 212 * @param callback 213 * @param file 214 * @param fileKey 215 * @throws IOException 216 */ 217 private void _postAsyn(String url, ResultCallback callback, File file, String fileKey) throws IOException 218 { 219 Request request = buildMultipartFormRequest(url, new File[]{file}, new String[]{fileKey}, null); 220 deliveryResult(callback, request); 221 } 222 223 /** 224 * 异步基于post的文件上传,单文件且携带其他form参数上传 225 * 226 * @param url 227 * @param callback 228 * @param file 229 * @param fileKey 230 * @param params 231 * @throws IOException 232 */ 233 private void _postAsyn(String url, ResultCallback callback, File file, String fileKey, Param... params) throws IOException 234 { 235 Request request = buildMultipartFormRequest(url, new File[]{file}, new String[]{fileKey}, params); 236 deliveryResult(callback, request); 237 } 238 239 /** 240 * 异步下载文件 241 * 242 * @param url 243 * @param destFileDir 本地文件存储的文件夹 244 * @param callback 245 */ 246 private void _downloadAsyn(final String url, final String destFileDir, final ResultCallback callback) 247 { 248 final Request request = new Request.Builder() 249 .url(url) 250 .build(); 251 final Call call = mOkHttpClient.newCall(request); 252 call.enqueue(new Callback() 253 { 254 @Override 255 public void onFailure(final Request request, final IOException e) 256 { 257 sendFailedStringCallback(request, e, callback); 258 } 259 260 @Override 261 public void onResponse(Response response) 262 { 263 InputStream is = null; 264 byte[] buf = new byte[2048]; 265 int len = 0; 266 FileOutputStream fos = null; 267 try 268 { 269 is = response.body().byteStream(); 270 File file = new File(destFileDir, getFileName(url)); 271 fos = new FileOutputStream(file); 272 while ((len = is.read(buf)) != -1) 273 { 274 fos.write(buf, 0, len); 275 } 276 fos.flush(); 277 //如果下载文件成功,第一个参数为文件的绝对路径 278 sendSuccessResultCallback(file.getAbsolutePath(), callback); 279 } catch (IOException e) 280 { 281 sendFailedStringCallback(response.request(), e, callback); 282 } finally 283 { 284 try 285 { 286 if (is != null) is.close(); 287 } catch (IOException e) 288 { 289 } 290 try 291 { 292 if (fos != null) fos.close(); 293 } catch (IOException e) 294 { 295 } 296 } 297 298 } 299 }); 300 } 301 302 private String getFileName(String path) 303 { 304 int separatorIndex = path.lastIndexOf("/"); 305 return (separatorIndex < 0) ? path : path.substring(separatorIndex + 1, path.length()); 306 } 307 308 // /** 309 // * 加载图片 310 // * 311 // * @param view 312 // * @param url 313 // * @throws IOException 314 // */ 315 // private void _displayImage(final ImageView view, final String url, final int errorResId) 316 // { 317 // final Request request = new Request.Builder() 318 // .url(url) 319 // .build(); 320 // Call call = mOkHttpClient.newCall(request); 321 // call.enqueue(new Callback() 322 // { 323 // @Override 324 // public void onFailure(Request request, IOException e) 325 // { 326 // setErrorResId(view, errorResId); 327 // } 328 // 329 // @Override 330 // public void onResponse(Response response) 331 // { 332 // InputStream is = null; 333 // try 334 // { 335 // is = response.body().byteStream(); 336 // ImageUtils.ImageSize actualImageSize = ImageUtils.getImageSize(is); 337 // ImageUtils.ImageSize imageViewSize = ImageUtils.getImageViewSize(view); 338 // int inSampleSize = ImageUtils.calculateInSampleSize(actualImageSize, imageViewSize); 339 // try 340 // { 341 // is.reset(); 342 // } catch (IOException e) 343 // { 344 // response = _getAsyn(url); 345 // is = response.body().byteStream(); 346 // } 347 // 348 // BitmapFactory.Options ops = new BitmapFactory.Options(); 349 // ops.inJustDecodeBounds = false; 350 // ops.inSampleSize = inSampleSize; 351 // final Bitmap bm = BitmapFactory.decodeStream(is, null, ops); 352 // mDelivery.post(new Runnable() 353 // { 354 // @Override 355 // public void run() 356 // { 357 // view.setImageBitmap(bm); 358 // } 359 // }); 360 // } catch (Exception e) 361 // { 362 // setErrorResId(view, errorResId); 363 // 364 // } finally 365 // { 366 // if (is != null) try 367 // { 368 // is.close(); 369 // } catch (IOException e) 370 // { 371 // e.printStackTrace(); 372 // } 373 // } 374 // } 375 // }); 376 // 377 // 378 // } 379 // 380 // private void setErrorResId(final ImageView view, final int errorResId) 381 // { 382 // mDelivery.post(new Runnable() 383 // { 384 // @Override 385 // public void run() 386 // { 387 // view.setImageResource(errorResId); 388 // } 389 // }); 390 // } 391 392 393 //*************对外公布的方法************ 394 395 396 public static Response getAsyn(String url) throws IOException 397 { 398 return getInstance()._getAsyn(url); 399 } 400 401 402 public static String getAsString(String url) throws IOException 403 { 404 return getInstance()._getAsString(url); 405 } 406 407 public static void getAsyn(String url, ResultCallback callback) 408 { 409 getInstance()._getAsyn(url, callback); 410 } 411 412 public static Response post(String url, Param... params) throws IOException 413 { 414 return getInstance()._post(url, params); 415 } 416 417 public static String postAsString(String url, Param... params) throws IOException 418 { 419 return getInstance()._postAsString(url, params); 420 } 421 422 public static void postAsyn(String url, final ResultCallback callback, Param... params) 423 { 424 getInstance()._postAsyn(url, callback, params); 425 } 426 427 428 public static void postAsyn(String url, final ResultCallback callback, Map<String, String> params) 429 { 430 getInstance()._postAsyn(url, callback, params); 431 } 432 433 434 public static Response post(String url, File[] files, String[] fileKeys, Param... params) throws IOException 435 { 436 return getInstance()._post(url, files, fileKeys, params); 437 } 438 439 public static Response post(String url, File file, String fileKey) throws IOException 440 { 441 return getInstance()._post(url, file, fileKey); 442 } 443 444 public static Response post(String url, File file, String fileKey, Param... params) throws IOException 445 { 446 return getInstance()._post(url, file, fileKey, params); 447 } 448 449 public static void postAsyn(String url, ResultCallback callback, File[] files, String[] fileKeys, Param... params) throws IOException 450 { 451 getInstance()._postAsyn(url, callback, files, fileKeys, params); 452 } 453 454 455 public static void postAsyn(String url, ResultCallback callback, File file, String fileKey) throws IOException 456 { 457 getInstance()._postAsyn(url, callback, file, fileKey); 458 } 459 460 461 public static void postAsyn(String url, ResultCallback callback, File file, String fileKey, Param... params) throws IOException 462 { 463 getInstance()._postAsyn(url, callback, file, fileKey, params); 464 } 465 466 // public static void displayImage(final ImageView view, String url, int errorResId) throws IOException 467 // { 468 // getInstance()._displayImage(view, url, errorResId); 469 // } 470 // 471 // 472 // public static void displayImage(final ImageView view, String url) 473 // { 474 // getInstance()._displayImage(view, url, -1); 475 // } 476 477 public static void downloadAsyn(String url, String destDir, ResultCallback callback) 478 { 479 getInstance()._downloadAsyn(url, destDir, callback); 480 } 481 482 //**************************** 483 484 485 private Request buildMultipartFormRequest(String url, File[] files, 486 String[] fileKeys, Param[] params) 487 { 488 params = validateParam(params); 489 490 MultipartBuilder builder = new MultipartBuilder() 491 .type(MultipartBuilder.FORM); 492 493 for (Param param : params) 494 { 495 builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + param.key + "\""), 496 RequestBody.create(null, param.value)); 497 } 498 if (files != null) 499 { 500 RequestBody fileBody = null; 501 for (int i = 0; i < files.length; i++) 502 { 503 File file = files[i]; 504 String fileName = file.getName(); 505 fileBody = RequestBody.create(MediaType.parse(guessMimeType(fileName)), file); 506 //TODO 根据文件名设置contentType 507 builder.addPart(Headers.of("Content-Disposition", 508 "form-data; name=\"" + fileKeys[i] + "\"; filename=\"" + fileName + "\""), 509 fileBody); 510 } 511 } 512 513 RequestBody requestBody = builder.build(); 514 return new Request.Builder() 515 .url(url) 516 .post(requestBody) 517 .build(); 518 } 519 520 private String guessMimeType(String path) 521 { 522 FileNameMap fileNameMap = URLConnection.getFileNameMap(); 523 String contentTypeFor = fileNameMap.getContentTypeFor(path); 524 if (contentTypeFor == null) 525 { 526 contentTypeFor = "application/octet-stream"; 527 } 528 return contentTypeFor; 529 } 530 531 532 private Param[] validateParam(Param[] params) 533 { 534 if (params == null) 535 return new Param[0]; 536 else return params; 537 } 538 539 private Param[] map2Params(Map<String, String> params) 540 { 541 if (params == null) return new Param[0]; 542 int size = params.size(); 543 Param[] res = new Param[size]; 544 Set<Map.Entry<String, String>> entries = params.entrySet(); 545 int i = 0; 546 for (Map.Entry<String, String> entry : entries) 547 { 548 res[i++] = new Param(entry.getKey(), entry.getValue()); 549 } 550 return res; 551 } 552 553 private static final String SESSION_KEY = "Set-Cookie"; 554 private static final String mSessionKey = "JSESSIONID"; 555 556 private Map<String, String> mSessions = new HashMap<String, String>(); 557 558 private void deliveryResult(final ResultCallback callback, Request request) 559 { 560 mOkHttpClient.newCall(request).enqueue(new Callback() 561 { 562 @Override 563 public void onFailure(final Request request, final IOException e) 564 { 565 sendFailedStringCallback(request, e, callback); 566 } 567 568 @Override 569 public void onResponse(final Response response) 570 { 571 try 572 { 573 final String string = response.body().string(); 574 if (callback.mType == String.class) 575 { 576 sendSuccessResultCallback(string, callback); 577 } else 578 { 579 Object o = mGson.fromJson(string, callback.mType); 580 sendSuccessResultCallback(o, callback); 581 } 582 583 584 } catch (IOException e) 585 { 586 sendFailedStringCallback(response.request(), e, callback); 587 } catch (com.google.gson.JsonParseException e)//Json解析的错误 588 { 589 sendFailedStringCallback(response.request(), e, callback); 590 } 591 592 } 593 }); 594 } 595 596 private void sendFailedStringCallback(final Request request, final Exception e, final ResultCallback callback) 597 { 598 mDelivery.post(new Runnable() 599 { 600 @Override 601 public void run() 602 { 603 if (callback != null) 604 callback.onError(request, e); 605 } 606 }); 607 } 608 609 private void sendSuccessResultCallback(final Object object, final ResultCallback callback) 610 { 611 mDelivery.post(new Runnable() 612 { 613 @Override 614 public void run() 615 { 616 if (callback != null) 617 { 618 try { 619 callback.onResponse(object); 620 } catch (JSONException e) { 621 e.printStackTrace(); 622 } 623 } 624 } 625 }); 626 } 627 628 private Request buildPostRequest(String url, Param[] params) 629 { 630 if (params == null) 631 { 632 params = new Param[0]; 633 } 634 FormEncodingBuilder builder = new FormEncodingBuilder(); 635 for (Param param : params) 636 { 637 builder.add(param.key, param.value); 638 } 639 RequestBody requestBody = builder.build(); 640 return new Request.Builder() 641 .url(url) 642 .post(requestBody) 643 .build(); 644 } 645 646 647 public static abstract class ResultCallback<T> 648 { 649 Type mType; 650 651 public ResultCallback() 652 { 653 mType = getSuperclassTypeParameter(getClass()); 654 } 655 656 static Type getSuperclassTypeParameter(Class<?> subclass) 657 { 658 Type superclass = subclass.getGenericSuperclass(); 659 if (superclass instanceof Class) 660 { 661 throw new RuntimeException("Missing type parameter."); 662 } 663 ParameterizedType parameterized = (ParameterizedType) superclass; 664 return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]); 665 } 666 667 public abstract void onError(Request request, Exception e); 668 669 public abstract void onResponse(T response) throws JSONException; 670 } 671 672 public static class Param 673 { 674 public Param() 675 { 676 } 677 678 public Param(String key, String value) 679 { 680 this.key = key; 681 this.value = value; 682 } 683 684 String key; 685 String value; 686 } 687 688 689 }
调用时
OkHttpClientManager.getAsyn("yourUrl", new OkHttpClientManager.ResultCallback<String>() { @Override public void onError(Request request, Exception e) { e.printStackTrace(); } @Override public void onResponse(String response) throws JSONException { JSONObject root = new JSONObject(response); if (root.getInt("code") == 0){ JSONObject dataObject = root.getJSONObject("data"); if(dataObject == null){ Log.e(TAG, "ERROR:dataObject is null."); }else { HomeModel homeModel = new HomeModel(dataObject); initPager(homeModel.getMarquees()); } }else { Log.e(TAG, "ERROR:code is not 0."); } } });
原文中可在onResponse中传递model,但是因为我这里服务器传过来的json不大一样,所以用了String,然后自己解析json