OkHttp快速上手 发表于 2017-10-09 | 分类于 技术博客 | 日志拦截器 注意两种拦截器的不同 123456789101112131415161718192021class LoggingInterceptor implements Interceptor { @Override public Response intercept(Interceptor.Chain chain) throws IOException { Request request = chain.request(); long t1 = System.nanoTime(); logger.info(String.format("Sending request %s on %s%n%s", request.url(), chain.connection(), request.headers())); Response response = chain.proceed(request); long t2 = System.nanoTime(); logger.info(String.format("Received response for %s in %.1fms%n%s", response.request().url(), (t2 - t1) / 1e6d, response.headers())); return response; }}OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new LoggingInterceptor()) .build(); Headers1234567891011121314151617private final OkHttpClient client = new OkHttpClient(); public void run() throws Exception { 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(); Response response = client.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")); } 配置12345678910int cacheSize = 10 * 1024 * 1024; // 10 MiBCache cache = new Cache(cacheDirectory, cacheSize);OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .cache(cache) .retryOnConnectionFailure(true) .build(); 单个配置 单个别请求需要单独设置时 123OkHttpClient client1 = client.newBuilder() .readTimeout(500, TimeUnit.MILLISECONDS) .build(); post 表单123456789101112private final OkHttpClient client = new OkHttpClient(); public void run() throws Exception { RequestBody formBody = new FormBody.Builder() .add("search", "Jurassic Park") .build(); Request request = new Request.Builder() .url("https://en.wikipedia.org/w/index.php") .post(formBody) .build(); Response response = client.newCall(request).execute(); post String1234567891011121314151617181920public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8"); private final OkHttpClient client = new OkHttpClient(); public void run() throws Exception { String postBody = "" + "Releases\n" + "--------\n" + "\n" + " * _1.0_ May 6, 2013\n" + " * _1.1_ June 15, 2013\n" + " * _1.2_ August 11, 2013\n"; Request request = new Request.Builder() .url("https://api.github.com/markdown/raw") .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody)) .build(); Response response = client.newCall(request).execute(); } post a file12345678910111213public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8"); private final OkHttpClient client = new OkHttpClient(); public void run() throws Exception { 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(); Response response = client.newCall(request).execute(); } post multipart12345678910111213141516171819202122private static final String IMGUR_CLIENT_ID = "..."; private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png"); private final OkHttpClient client = new OkHttpClient(); public void run() throws Exception { // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("title", "Square Logo") .addFormDataPart("image", "logo-square.png", RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png"))) .build(); Request request = new Request.Builder() .header("Authorization", "Client-ID " + IMGUR_CLIENT_ID) .url("https://api.imgur.com/3/image") .post(requestBody) .build(); Response response = client.newCall(request).execute()) } cancel 和 response 注意cancel和response的使用 123456789101112131415161718192021//当请求没有结束,会调用 onFailure 所以添加判断call.isCanceled()call.cancel();//查询是否取消call.isCanceled(); //查询是否执行过call.isExecuted(); //code >= 200 && code < 300 成功的状态码response.isSuccessful()//读取一次数据流就会关闭,再出读取为nullresponse.body().string()//记得关闭resopnseResponse.close();Response.body().close();Response.body().source().close();Response.body().charStream().close();Response.body().byteString().close();Response.body().bytes();Response.body().string();//Call对象只能执行一次请求Call reCall=client.newCall(call.request()); //获取另一个相同配置的Call对 简单封装 封装成一个工具类,直接上代码 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213public class OkHttpHelper { public static OkHttpHelper mInstance; private OkHttpClient mClient; private Handler mHandler; //构造方法 初始化请求客户端 private OkHttpHelper(Context context) { File sdcache = context.getExternalCacheDir(); int cacheSize = 10 * 1024 * 1024; mClient = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .addInterceptor(new LoggingInterceptor()) .cache(new Cache(sdcache.getAbsoluteFile(), cacheSize)) .build(); //ui线程looper mHandler = new Handler(Looper.getMainLooper()); } public static OkHttpHelper getInstance(Context context) { if (mInstance == null) { synchronized (OkHttpHelper.class) { if (mInstance == null) { mInstance = new OkHttpHelper(context); } } } return mInstance; } //返回ok public OkHttpClient getOkClient() { return mClient; } //根据标记取消任务 public void cancelCallWithTag(String tag) { //取消还未运行的 for (Call call : mClient.dispatcher().queuedCalls()) { if (call.request().tag().equals(tag)) call.cancel(); } //取消正在运行的 for (Call call : mClient.dispatcher().runningCalls()) { if (call.request().tag().equals(tag)) call.cancel(); } } //get异步请求 public void getRequest(@NonNull String url, String tag, Map<String, String> params, OkCallBack callBack) { if (params == null) { params = new HashMap<>(); } if (TextUtils.isEmpty(tag)) { tag = url; } //拼接地址 String requestUrl = urlJoint(url, params); Request request = new Request.Builder() .url(requestUrl) .tag(tag) .build(); Call call = mClient.newCall(request); dealResult(call, callBack); } //post异步请求 public void postRequest(@NonNull String url, String tag, Map<String, String> params, OkCallBack callBack) { //请求体 RequestBody requestBody; if (params == null) { params = new HashMap<>(); } if (TextUtils.isEmpty(tag)) { tag = url; } FormBody.Builder builder = new FormBody.Builder(); for (Map.Entry<String, String> map : params.entrySet()) { String key = map.getKey(); String value; //判断值是否是空的 if (map.getValue() == null) { value = ""; } else { value = map.getValue(); } //把key和value添加到formbody中 builder.add(key, value); } requestBody = builder.build(); Request request = new Request.Builder() .url(url) .post(requestBody) .tag(tag) .build(); Call call = mClient.newCall(request); dealResult(call, callBack); } //post异步请求及文件,自己构造requestBody public void postRequestMultipart(@NonNull String url, String tag, RequestBody requestBody, OkCallBack callBack) { if (TextUtils.isEmpty(tag)) { tag = url; } Request request = new Request.Builder() .url(url) .post(requestBody) .tag(tag) .build(); Call call = mClient.newCall(request); dealResult(call, callBack); } //post异步上传单文件 public void postOnlyFile(@NonNull String url, MediaType mediaType, String tag, File file, OkCallBack callBack) { if (TextUtils.isEmpty(tag)) { tag = url; } Request request = new Request.Builder() .url(url) .post(RequestBody.create(mediaType,file)) .tag(tag) .build(); Call call = mClient.newCall(request); dealResult(call, callBack); } //处理结果 private void dealResult(Call call, final OkCallBack callBack) { call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { sendFailCallback(call, e, callBack); } @Override public void onResponse(Call call, Response response) throws IOException { sendSuccessCallBack(call,response, callBack); } }); } //成功响应 private void sendSuccessCallBack(final Call call, final Response response, final OkCallBack callBack) { if (callBack != null) { mHandler.post(new Runnable() { @Override public void run() { try { callBack.onResponse(call,response); } catch (IOException e) { e.printStackTrace(); } } }); } } //失败响应 private void sendFailCallback(final Call call, final IOException e, final OkCallBack callBack) { mHandler.post(new Runnable() { @Override public void run() { if (callBack != null) { callBack.onError(call, e); } } }); } /** * 拼接url和请求参数 * * @param url url * @param params key value * @return String url */ private static String urlJoint(String url, Map<String, String> params) { StringBuilder endUrl = new StringBuilder(url); boolean isFirst = true; Set<Map.Entry<String, String>> entrySet = params.entrySet(); for (Map.Entry<String, String> entry : entrySet) { if (isFirst && !url.contains("?")) { isFirst = false; endUrl.append("?"); } else { endUrl.append("&"); } endUrl.append(entry.getKey()); endUrl.append("="); endUrl.append(entry.getValue()); } return endUrl.toString(); }}