Gradle 引入依赖
implementation 'com.squareup.okhttp3:okhttp:3.14.7' implementation 'com.squareup.okio:okio:1.17.5'2、 Manifest 申请网络权限
3、基本用法
- 第一步: 构建OKHttpClient对象
- 第二步:构建Request请求对象
- 第三步:生成CALL对象
- 第四步:call 发起网络请求(同步/异步)
//1、构建okhttpClient 对象 OkHttpClient okHttpClient = new OkHttpClient(); // 2、 构建request请求对象 Request request = new Request.Builder().url("www.baidu.com").get().build(); // 3、生成call对象 Call call = okHttpClient.newCall(request); // 4、 发起同步请求,同步请求要放在子线程中 new Thread(new Runnable() { @Override public void run() { try { Response response = call.execute(); } catch (IOException e){ e.printStackTrace(); } } }).start();3.2 GET 异步请求
如果要主线程中直接使用,不单独新建子线程,可以用异步请求.
//1.构建okHttpClient对象 OkHttpClient okHttpClient = new OkHttpClient(); //2.构建request请求对象 Request request = new Request.Builder().url("www.baidu.com").get().build(); //3.生成call对象 Call call = okHttpClient.newCall(request); //4.异步请求 call.enqueue(new Callback() { @Override public void onFailure(@NotNull Call call, @NotNull IOException e) { } @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { Log.e(TAG,"okhttp get enqueue:" + response.body().string()); ResponseBody body = response.body(); String string = body.string(); byte[] bytes = body.bytes(); InputStream inputStream = body.byteStream(); } });
call.enqueue会异步执行,其实,两个回调方法 onFailure 和onResponse都是执行在子线程的,因此想要执行UI *** 作,需要使用Handle切换到UI线程。
3.3 同步POST请求POST请求与GET请求的区别:在构造Requeset对象时,需要多构建一个RequestBody对象,来携带我们提交的数据。
//1.构建okHttpClient对象 OkHttpClient okHttpClient = new OkHttpClient(); //2.构建RequestBody对象 RequestBody body = new FormBody.Builder() .add("ip", "58.188.54.36") .build(); //3.构建request请求对象,将RequestBody传入request对象 Request request = new Request.Builder() .url("www.baidu.com") .post(body) .build(); //4.生成call对象 Call call = okHttpClient.newCall(request); //5.同步请求 new Thread(new Runnable() { @Override public void run() { try { Response response = call.execute(); Log.e(TAG, "okhttp POST execute" + response.body().string()); } catch (IOException e) { e.printStackTrace(); } } }).start();
在构建Request的时候,将get()替换成post(body),并且传入requestBody实例.如果构建Request的时候,不指定请求方法时,默认为GET请求。
3.4 POST异步请求//1.构建okHttpClient对象 OkHttpClient okHttpClient = new OkHttpClient(); //2.构建RequestBody对象 RequestBody body = new FormBody.Builder() .add("ip", "58.188.54.36") .build(); //3.构建request请求对象,将RequestBody传入request对象 Request request = new Request.Builder() .url("www.baidu.com") .post(body) .build(); //4.生成call对象 Call call = okHttpClient.newCall(request); //5.异步请求 call.enqueue(new Callback() { @Override public void onFailure(@NotNull Call call, @NotNull IOException e) { } @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { Log.e(TAG, "okhttp POST execute" + response.body().string()); } });3.5 异步上传文件
//1.构建okHttpClient对象 OkHttpClient okHttpClient = new OkHttpClient(); //2.构建RequestBody对象 //2.1 文件类型 MediaType contentType = MediaType.parse("text/x-markdown;charset=utf-8"); //2.2 文件内容 string String content = "xiaomi"; RequestBody requestBody = RequestBody.create(contentType, content); //3.构建request请求对象,将RequestBody传入request对象 Request request = new Request.Builder() .url("www.baidu.com") .post(requestBody) .build(); //4.生成call对象 Call call = okHttpClient.newCall(request); //5.异步请求 call.enqueue(new Callback() { @Override public void onFailure(@NotNull Call call, @NotNull IOException e) { } @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { Log.e(TAG, "okhttp POST execute" + response.body().string()); } });
打印结果
okHttpPost enqueue: onResponse:Response{protocol=http/1.1, code=200, message=OK, url=https://api.github.com/markdown/raw} body:xiaoomi
具体的文件上传示例
首先在SD卡里面创建一个xioami.txt文件,里面的内容为"okhttp"
//1.构建okHttpClient对象 OkHttpClient okHttpClient = new OkHttpClient(); //2.构建RequestBody对象, //2.1 定义上传文件的文件类型 MediaType contentType = MediaType.parse("text/x-markdown;charset=utf-8"); //文件路径 String filePath = ""; //判断当前文件的类型 if (Environment.getExternalStorageState().equals(contentType)) { filePath = Environment.getExternalStorageDirectory().getAbsolutePath(); } else { return null; } File file = new File(filePath, "xiaomi.txt"); //2.2 创建requestBody,将文件传入 RequestBody requestBody = RequestBody.create(contentType, file); //3.构建request请求对象,将RequestBody传入request对象 Request request = new Request.Builder() .url("www.baidu.com") .post(requestBody) .build(); //4.生成call对象 Call call = okHttpClient.newCall(request); //5.异步请求 call.enqueue(new Callback() { @Override public void onFailure(@NotNull Call call, @NotNull IOException e) { } @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { Log.e(TAG, "okhttp POST execute" + response.body().string()); } });
看完之后,感觉有点懵逼,怎么构建RequestBody的时候,有的时候用 ReuqestBody.create()来构建,有的时候用FormBody构建?这是为什么呢?
FormBody是RequestBody的子类,FromBody 用于提交表单键值对,能够满足我们平常大部分的开发需求。
//RequestBody:FormBody,表单键值对 RequestBody formBody = new FormBody.Builder() .add("username", "hfy") .add("password", "qaz") .build();
当然除了FormBody之外,RequestBody还有一个子类---MultipartyBody,用于post请求提交复杂类型的请求体.复杂请求体可以同时包含多种类型的请求数据.
3.6 异步上传Multiparty 文件//1.构建okHttpClient对象 OkHttpClient okHttpClient = new OkHttpClient(); //2.构建RequestBody对象, //2.1 定义上传文件的文件类型 MediaType contentType = MediaType.parse("text/x-markdown;charset=utf-8"); MultipartBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("title", "xiaomi") .addFormDataPart("dress", "kejiyuan") .addFormDataPart("image", "xm.jpg", RequestBody.create(contentType, new File("/sdcard/xiaomi.jpg"))) .build(); //3.构建request请求对象,将RequestBody传入request对象 Request request = new Request.Builder() .url("www.baidu.com") .post(requestBody) .build(); //4.生成call对象 Call call = okHttpClient.newCall(request); //5.异步请求 call.enqueue(new Callback() { @Override public void onFailure(@NotNull Call call, @NotNull IOException e) { } @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { Log.e(TAG, "okhttp POST execute" + response.body().string()); } });
在构建RequestBody的时候,使用的MultipartyBody构建的MultipartBody实例,前两个上传的是键值对,第三个上传的是表单.addformDatapart方法的第一个参数是key,第二个是上传文件的名子,第三个参数是需要上传的文件。
3.7 请求配置项问题:
1.如何全局设置超时时长?
2.缓存位置,最大缓存大小呢?
3.要监控App通过okhttp发送的所有请求,以及整个请求的所有耗时时间呢?
//1.构建okHttpClient对象 OkHttpClient okHttpClient = new OkHttpClient.Builder() .connectTimeout(15, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .cache(new Cache(new File("/sdcard/xiaomi.jpg"),500*1024*1024)) .addInterceptor(new Interceptor() { @NotNull @Override public Response intercept(@NotNull Chain chain) throws IOException { Request request = chain.request(); String url = request.url().toString(); Log.i(TAG, "intercept: proceed start: url"+ url+ ", at "+System.currentTimeMillis()); Response response = chain.proceed(request); ResponseBody body = response.body(); Log.i(TAG, "intercept: proceed end: url"+ url+ ", at "+System.currentTimeMillis()); return response; } }) .build();
这里通过OK HTTPClient.Builder构建者模式设置了连接,读取,写入的超时时间,缓存cache()方法传入了有缓存目录,缓存大小构成的Cache实例.
同时,使用addInterceptor()方法添加了interceptor实例,重写了interceptor方法.interceptor为拦截器,在执行请求的时候会调用,其中chain.procee(request) 是内部真正请求的过程,是个阻塞过程,执行完毕之后,就会得到response.所以在该前后去当时时间,就可以得知整个请求的耗时。
除了全局设置之外,还可以对单个请求进行设置.
Request request = new Request.Builder() .url("www.baidu.com") .post(requestBody) .addHeader("key","value") .cacheControl(CacheControl.FORCE_CACHE) .build();
addHeader()方法添加了请求头
cacheControl(CacheControl.FORCE_NETWORK) 设置此次请求只能使用网络,不能用缓存.
3.8 取消请求使用call.cancel()可以立马取消一个正在执行的call.当用户离开一个应用时,或者跳转到其他的界面时,使用call.cancel()可以节约网络资源;此外,不管同步或者异步的call都可以取消,也可以通过tag来同时取消多个请求.但构建一个请求的时候,通过request.builder.tag()来分配一个标签,之后就可以用okhttpclient.cancel(tag)来取消所有带标签的请求.
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); private void cancel() { OkHttpClient okHttpClient = new OkHttpClient.Builder().build(); final Request request = new Request.Builder() .url("www.baidu.com") .cacheControl(CacheControl.FORCE_NETWORK) .build(); Call call = okHttpClient.newCall(request); executorService.schedule(new Runnable() { @Override public void run() { call.cancel(); } },10,TimeUnit.MICROSECONDS); } call.enqueue(new Callback() { @Override public void onFailure(@NotNull Call call, @NotNull IOException e) { } @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { if (response.cacheResponse() != null) { Log.e(TAG, "cache" + response.cacheResponse().toString()); } else { Log.e(TAG, "network" + response.networkResponse().toString()); } } });
参考:Android进阶之光
网络请求框架OkHttp3全解系列(一):OkHttp的基本使用
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)