Android网络请求框架之Okhttp3.0 详细使用
Posted 有头发的程序猿#
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android网络请求框架之Okhttp3.0 详细使用相关的知识,希望对你有一定的参考价值。
一.OKhttp介绍
除了android原生的HttpURLConnection的网络通信之外,还有其他许多优秀的网路通信库,而Okhttp无疑是其中出色的一种。Okhttp是Square公司开发的,Okhttp官网主页是:https://github.com/square/okhttp
二.Okhttp基础使用
首先在官网找到最新的Okhttp依赖:我这里最新版是4.9.0
implementation("com.squareup.okhttp3:okhttp:4.9.0")
我们最常用的是get和post的两种请求方法
1.get方法
private static final String TAG = "MainActivity";
OkHttpClient client = new OkHttpClient();
String url = "https://www.baidu.com/";
Request request = new Request.Builder()
.url(url)
.build();
new Thread(new Runnable()
@Override
public void run()
try
Response response = client.newCall(request).execute();
Log.i(TAG, "responseBody "+response.body().string());
catch (IOException e)
e.printStackTrace();
).start();
1.这里首先要创建一个OkhttpClient对象
2. 接着想要发起http请求的话就需要创建一个Request对象,通过.url()来设置get的url地址,如需参数,直接连在url中,如"https://service?username=111&pwd=222"
3. 构建好request对象后,需要调用okhttp对象的newCall()方法将我们的request放进去,来创建一个Call对象,在调用call对象的execute()方法来得到我们请求的返回体。调用返回体的body().string()得到服务器返回给我们的String数据。
4. 特别注意call对象有两种请求,一种是execute的同步请求,另一个是enquene()异步请求。同步请求会阻塞,故而在子线程中开启。
2.post方法
接下来我们说一下post方法结合异步请求enquene()
String url="..."
OkHttpClient client = new OkHttpClient();
RequestBody body = new FormBody.Builder()
.add("username","111")
.add("pwd","222")
.build();
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
client.newCall(request).enqueue(new Callback()
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e)
runOnUiThread(new Runnable()
@Override
public void run()
Toast.makeText(MainActivity2.this,"请求失败",Toast.LENGTH_SHORT).show();
);
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
runOnUiThread(new Runnable()
@Override
public void run()
Toast.makeText(MainActivity.this,"请求成功"+response.body().string(),Toast.LENGTH_SHORT).show();
);
);
- 首先post请求我们只需要构建一个RequestBody请求对象就好了,这里注意点是new FormBody.Build().add().build()方式构建,再在request里post这个请求体就行了。
- 第二点异步请求enquene(),里面需要传一个callBack接口回调,用来处理我们返回的信息,异步请求已经默认是在子线程中执行了,不需要我们自己开启。onFailure是返回失败的方法,onResponse是返回成功的。返回成功不一定是请求成功到需要的数据,我们通过response.isSuccessful()来判断,因为返回的请求码为200才是成功的。
- 当我们在里面执行主线程ui操作的时候记得调用runOnUiThread方法切回主线程中执行
一般我们会吧请求封装在一个类里面方便我们使用
public class HttpUtil
public static void request(String url,okhttp3.Callback callback)
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(callback);
三.post进阶使用
协议规定post请求提交的数据必须在请求体中,我们上面的FormBody()是表单类型的,一般我们协议没有规定使用什么的编码方式,而所有的编码方式如下: https://www.runoob.com/http/http-content-type.html.
下面是一些常见的:
- application/x-www-form-urlencoded : 中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式),Formbody也就是这种
- Content-Type: multipart/form-data :数据被编码成一条信息,一般用于文件上传
- application/octet-stream : 二进制流数据(如常见的文件下载提交),如果用于文件上传,只能用于一个文件的提交
- application/json: JSON数据格式
上传多个text文件
File file1 = new File("1.txt");
File file2 = new File("2.txt");
OkHttpClient client = new OkHttpClient();
RequestBody requestBody1 = RequestBody.create(file1, MediaType.parse("text/plain"));
RequestBody requestBody2 = RequestBody.create(file2, MediaType.parse("text/plain"));
MultipartBody body = new MultipartBody.Builder()
.addFormDataPart("file1",file1.getName(),requestBody1)
.addFormDataPart("file2",file2.getName(),requestBody2)
.build();
Request request = new Request.Builder()
.url("...")
.post(body)
.build();
Call call = client.newCall(request);
try
Response response = call.execute();
System.out.println(response.body().string());;
catch (IOException e)
e.printStackTrace();
-
需要构建传输文件的requestBody,通过create构建,第二个参数是MediaType.parse(“text/plain”),因为我们上传的文件是text纯文本,具体什么格式可以去上面编码网站查。
-
接着通过MultipartBody来构建多个requestbody,其他步骤一致
上传json文件
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = RequestBody.create("\\"a\\":1,\\"b\\":2",MediaType.parse("application/json"));
Request request = new Request.Builder()
.url("...")
.post(requestBody)
.build();
Call call = client.newCall(request);
try
Response response = call.execute();
System.out.println(response.body().string());;
catch (IOException e)
e.printStackTrace();
四.Okhttp的配置
1.okhttp的拦截器
OkHttpClient client1 = new OkHttpClient.Builder().addInterceptor(new Interceptor()
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException
Request request = chain.request().newBuilder()
.addHeader("Os","android").addHeader("version","1.0").build();
Response response = chain.proceed(request);
return response;
).addNetworkInterceptor(new Interceptor()
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException
System.out.println(chain.request().headers());
return chain.proceed(chain.request());
).build();
1.首先addInterceptor()和addNetworkInterceptor()都是给okhttp添加拦截器,但是执行顺序是谴责高于后者,如果是同种类型的,则是先添加先执行。
2. 拦截器的作用是可以给我们的所有request在请求前加上统一的处理,比如添加请求头之类的
3. 具体使用看代码就ok,模板就是这样。
2.okhttp的缓存
Okhttp按照了http协议规则实现了缓存的处理,比如如果我们进行了第一次请求之后,还要进行相同的请求,此时如果符合缓存的规则的话,就可以减少直接与服务器进行网络通信,可以直接从本地的缓存中读取响应给缓存者。但是默认情况下okhttp的缓存是关闭的,故而需要我们的手动开启。使用方法如下,加入.cache,需要cache对象,该对象第一个参数是文件路径,第二个是大小。
OkHttpClient client = new OkHttpClient.Builder()
.cache(new Cache(new File("/path/cache"),1024*1024)).build();
3.okhttp的cookie
cookie是网站为了识别用户的身份,进行会话跟踪,例如登录信息要保存在本地的一个文件上,该cookie文件是加了密的,由客户端暂时或者永久性的进行保存。
OkHttpClient client1
= new OkHttpClient.Builder()
.cookieJar(new CookieJar()
@Override
public void saveFromResponse(@NotNull HttpUrl httpUrl, @NotNull List<Cookie> list)
map.put(httpUrl.host(),list);
@NotNull
@Override
public List<Cookie> loadForRequest(@NotNull HttpUrl httpUrl)
return map.containsKey(httpUrl.host())?map.get(httpUrl.host()):new ArrayList<Cookie>() ;
).build();
这里我们需要给我们okhttp配置一个cookieJar,重写接口的两个方法,第一个是我们保存服务器返回给我们的cookie,比如我们登录时候,服务器返回验证了我们身份的cookie,我们一般需要得到它并且写在本地的文件上,但我这里为了方便写在了一个map里面。第二个根据我们请求的网址判断我们有没有该网址缓存的cookie。有的话,我们就可以直接使用不需要登录。
五.总结
基本的okhttp用法我已经列举了出来,如果有什么建议的地方欢迎评论区留言,接下来我会准备写另一个网络请求框架Retrofit的使用.
以上是关于Android网络请求框架之Okhttp3.0 详细使用的主要内容,如果未能解决你的问题,请参考以下文章