Android网络请求框架----Okhttp3完全解析(1),使用篇

1.前言:

最近在改项目的时候发现以前的项目网络请求框架是XUtils,这在过去是一个比较流行的框架,功能强大而且比较全面,但是就XUtils本身的网络请求模块而言,因为Google在android6.0中已经将HttpClient部分给删除,当我把开发工具的compileSdkVersion调到23以上,该框架就会出错,Volley这个框架也是一样,内部也是HttpClient和HttpUrlConnection实现的,所以如果你的项目中还是用了这些古老的框架,还是赶紧换吧。

先来看一张okhttp的脑图(copy而来的)
Android网络请求框架----Okhttp3完全解析(1),使用篇_第1张图片

2.使用:

2.1 集成:

androidstudio直接在gradle中添加:
dependencies
{
compile ‘com.squareup.okhttp3:okhttp:3.5.0’
}
在manifest中添加网络权限。

2.2 使用类型:

2.2.1 Get方式:

步骤: new OkHttpClient ()
Request.Builder方便添加header
call.enqueue异步执行

//get请求方式
    private void httpGet() {
        String url="http://www.baidu.com";
        //client对象,核心类
        OkHttpClient client=new OkHttpClient();
        //构建者模式,url地址,get方式,
//        final Request request=new Request.Builder().url(url).get().build();

        //用requestBuilder可以添加header
        Request.Builder requestBuilder = new Request.Builder().url(url);
        requestBuilder.addHeader("key","value")

        Request request=requestBuilder.build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //子线程中
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String str=response.body().string();

             //子线程中,response.body()中既可以获取String,也可以获取成byte数组,或者是stream
            }
        });

    }

注意:callback中的failure和success的方法都是在非ui线程中,如果涉及到控件的刷新,一定要在主线程中进行处理。
OkHttp的添加header有两种方式:
使用 header(name,value) 来设置HTTP头的唯一值,相同的key值会覆盖
使用 addHeader(name,value) 来补充新值,不会覆盖相同的key值
使用 header(name) 读取唯一值或多个值的最后一个值
使用 headers(name) 获取所有值

2.2.2 表单提交(key-value形式)

 //键值对参数提交(表单提交)
    private void httpPost() {
        String url="";
        //client对象,核心类
        OkHttpClient client=new OkHttpClient();
        //构建者模式,url地址,get方式,
//        final Request request=new Request.Builder().url(url).get().build();


        //这里面添加参数
        RequestBody requestbody=new FormBody.Builder()
                .add("key1","param1")
                .add("key2","param2")
                .build();
        //用requestBuilder可以添加header
        Request.Builder requestBuilder = new Request.Builder().url(url).post(requestbody);

        requestBuilder.addHeader("key","value");

        Request request=requestBuilder.build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //子线程中
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String str=response.body().string();
                //子线程中
            }
        });
    }

2.2.3请求体是一个JSON格式的数据

 private void httpPostJson() {
        String url="";
        //client对象,核心类
        OkHttpClient client=new OkHttpClient();

        //这里面添加参数
        Map<String,String> map=new HashMap<>();
        map.put("key1","param1");
        map.put("key2","param2");
        map.put("key3","param3");

    //这里用的是fastjson进行解析的
        String jsonstr= JSON.toJSONString(map);
        RequestBody requestbody = RequestBody.create(MediaType.parse("application/json"), jsonstr);
        //用requestBuilder可以添加header
        Request.Builder requestBuilder = new Request.Builder().url(url).post(requestbody);
        requestBuilder.addHeader("key","header1");

        Request request=requestBuilder.build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //子线程中
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String str=response.body().string();
                //子线程中
            }
        });
    }

post的代码也比较简单,相信大家肯定能都看懂。但是在这里面涉及到一个比较重要的类MediaType,该类来指定post上传的参数类型。
FormBody涉及常见的有三种:
application/x-www-form-urlencoded 数据是个普通表单
multipart/form-data 数据里有文件
application/json 数据是个json
但是好像以上的普通表单并没有指定MediaType,这是因为FormBody继承了RequestBody,它已经指定了数据类型为application/x-www-form-urlencoded。

2.2.4 上传file文件(以图片为例)

   //文件的上传
    private void httpFileUp() {
        OkHttpClient client = new OkHttpClient();
        final MediaType MEDIA_TYPE_TEXT = MediaType.parse("image/png");
        File file=new File("wy.png");
        MultipartBody multipartBody=new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("file",file.getName(),RequestBody.create(MEDIA_TYPE_TEXT,file))
                .build();

        Request request = new Request.Builder()
                .url("http://www.baidu.com")
                .post(multipartBody)
                .build();
         client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
            }
        });

    }

对于文件上传,我们用RequestBody的另一个继承类MultipartBody,该类首先需要setType,这里面的参数参有五种类型:

  public static final MediaType MIXED = MediaType.parse("multipart/mixed");

  public static final MediaType ALTERNATIVE = MediaType.parse("multipart/alternative");

  public static final MediaType DIGEST = MediaType.parse("multipart/digest");

  public static final MediaType PARALLEL = MediaType.parse("multipart/parallel");

  public static final MediaType FORM = MediaType.parse("multipart/form-data");

源码中有相应的解释,当为FORM时,`final MediaType MEDIA_TYPE_TEXT = MediaType.parse(“image/png”);这行代码的类型指定参数可以参考:点击查看,如果接口没有file字段,直接上传文件,可以这样写:.post(RequestBody.create(MEDIA_TYPE_TEXT, file))

2.2.5 下载文件:

 private void httpFileDown() {
        OkHttpClient mOkHttpClient = new OkHttpClient();
        String url = "";
        Request request = new Request.Builder().url(url).build();
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) {
                InputStream inputStream = response.body().byteStream();
                FileOutputStream fileOutputStream = null;
                try {
                    fileOutputStream = new FileOutputStream(new File("/sdcard/wy.jpg"));
                    byte[] buffer = new byte[2048];
                    int len = 0;
                    while ((len = inputStream.read(buffer)) != -1) {
                        fileOutputStream.write(buffer, 0, len);
                    }
                    fileOutputStream.flush();
                } catch (IOException e) {

                }

            }
        });
    }

文件下载比较简单,其实就是一个get请求,获取到数据流后写进文件中即可。

总结:熟悉以上方法后,我们基本上能够应对android开发中的网络请求了,但是很明显,项目中的接口有很多,每次这样写肯定费事,而且OkHttpClient 一般一个项目中只需要一个全局对象,并且相关的参数比如参数,缓存也没有设置,所以这篇博客权当入门使用,感兴趣的可以看我的下一篇,Android网络请求框架—-Okhttp3完全解析(2),封装框架。

你可能感兴趣的:(github框架)