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();
                        
                    );

            
        );

  1. 首先post请求我们只需要构建一个RequestBody请求对象就好了,这里注意点是new FormBody.Build().add().build()方式构建,再在request里post这个请求体就行了。
  2. 第二点异步请求enquene(),里面需要传一个callBack接口回调,用来处理我们返回的信息,异步请求已经默认是在子线程中执行了,不需要我们自己开启。onFailure是返回失败的方法,onResponse是返回成功的。返回成功不一定是请求成功到需要的数据,我们通过response.isSuccessful()来判断,因为返回的请求码为200才是成功的。
  3. 当我们在里面执行主线程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.
下面是一些常见的:

  1. application/x-www-form-urlencoded : 中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式),Formbody也就是这种
  2. Content-Type: multipart/form-data :数据被编码成一条信息,一般用于文件上传
  3. application/octet-stream : 二进制流数据(如常见的文件下载提交),如果用于文件上传,只能用于一个文件的提交
  4. 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();
        

  1. 需要构建传输文件的requestBody,通过create构建,第二个参数是MediaType.parse(“text/plain”),因为我们上传的文件是text纯文本,具体什么格式可以去上面编码网站查。

  2. 接着通过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 详细使用的主要内容,如果未能解决你的问题,请参考以下文章

Android网络请求框架之Okhttp3.0 详细使用

Android 使用Retrofit2.0+OkHttp3.0实现缓存处理+Cookie持久化第三方库

Android网络请求框架之Retrofit

Android之封装好的异步网络请求框架

Android网络请求框架之Retrofit

Android网络请求框架之Retrofit