OkHttp 3 基本用法

OkHttp 也已经出来很久了,相信大家也都在项目中使用了,今天来对 OkHttp 使用进行一个简单的总结


一、概述


HTTP 是超文本传输协议,也是互联网上应用最为广泛的一种网络协议,高效的进行 HTTP 使用可以使你的东西更快的加载并节省带宽


OkHttp 是 HTTP 客户端的有效应用,OkHttp 处理了很多疑难杂症:

  • 例如会从很多常用连接问题中自动恢复
  • 如果你的服务器设置了多个 IP 地址,当第一个IP连接失败的时候,OkHttp 会自动尝试下一个 IP
  • OkHttp 还处理了代理服务器问题和 SSL 握手失败问题
  • 支持 HTTP/2,HTTP/2 通过使用多路复用技术在一个单独的 TCP 连接上支持并发,通过在一个连接上一次性发送多个请求来发送或接受数据
  • 如果 HTTP/2 不可用,连接池复用技术也可以极大地减少延迟

      使用 OkHttp 无需重写您程序中的网络代码,OkHttp 实现了几乎和 HttpURLConnection 一样的 API,OkHttp 支持 Android2.3 及以上

官网地址:http://square.github.io/okhttp/

GitHub 地址:https://github.com/square/okhttp


二、使用教程详解


首先使用前我们需要在 app 目录级别下的 build.gradle 中添加:

compile 'com.squareup.okhttp3:okhttp:3.8.1'


1. 异步 GET  请求


进行网络数据加载,想必第一个我们就得先来说 GET 请求,这里我们如果是新建的项目别忘了添加网络权限

  <uses-permission android:name="android.permission.INTERNET" />

    /**
     * 异步Get请求
     * @param view
     */
    public void getRequest(View view) {
        //创建 OkHttpClient 对象
        OkHttpClient okHttpClient = new OkHttpClient();
        //创建 Request
        Request request = new Request.Builder()
                .url("https://www.baidu.com/")
                .build();

        Call call = okHttpClient.newCall(request);
        //发送请求
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "失败------" + e.getLocalizedMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.e(TAG, "成功------" + response);
                String result = response.body().string();
                Log.e(TAG, result);

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(), "请求成功", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
    }

      以上我们就完成了一个异步 Get 请求,首先创建了 Okhttp 对象,并构造了 Request 对象,并传入了一个 url,主意这里Request.Builder 还可以设置如 header、method 等的参数方法,然后通过 request 的对象去构造得到一个 Call 对象,最后我们调用Call 对象的 enqueue() 来执行,注意这里也可以选择同步 execute() 请求,将 call 加入到调度队列,然后等待执行完成,在 Callback 中得到回调结果,这里我们需要注意的就是,onResponse 回调的参数是 reponse,一般来说,如果我们希望获得返回的是字符串,可以通过 response.body().string() 获取,如果希望获得返回的二进制节数组,则通过 response.body().bytes() 等


2. 异步POST请求


    /**
     * 异步Post请求
     *
     * @param view
     */
    public void postRequest(View view) {
        //创建 OkHttpClient 对象
        OkHttpClient okHttpClient = new OkHttpClient();
        //构建 RequestBody
        RequestBody formBody = new FormBody.Builder()
                .add("键", "值")
                .build();
        //构建 Request
        Request request = new Request.Builder()
                .url("https://www.baidu.com/")
                .post(formBody)
                .build();

        Call call = okHttpClient.newCall(request);
        //发送请求
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "失败------" + e.getLocalizedMessage());
            }

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

                Log.e(TAG, "成功------" + response);
                String result = response.body().string();
                Log.e(TAG, result);

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(), "请求成功", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
    }

      这里需要注意一下 OkHttp3 异步 POST 请求和 OkHttp2.x 有一点区别就是没有 FormEncodingBuilder 这个类,替代它的就是FormBody,大家都知道,post 的时候,参数是包含在请求体中的,所以我们通过 FormBody 来添加多个 String 键值对,然后去构造 RequestBody,来完成我们 Request 的构造,后面的步骤基本就和 get 请求一样了,还有就是这了提交的表单格式可以有多种

如果表单是 json:

        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(JSON, "你的json");

如果数据包含文件:

        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("image/png"), file))
                .build();

接下来我们将会讲具体解到


3. 异步上传文件


定义上传文件得类型:

    //上传文件的类型
    public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");


    /**
     * 异步上传文件
     *
     * @param view
     */
    public void postFile(View view) {
        OkHttpClient okHttpClient = new OkHttpClient();
        File file = new File("上传的文件");
        Request request = new Request.Builder()
                .url("上传的地址")
                .post(RequestBody.create(MEDIA_TYPE_MARKDOWN,file))
                .build();

        Call call = okHttpClient.newCall(request);
        
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

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

            }
        });
    }

这里也要注意不要忘记添加权限:

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

可以看到上传文件其实也是一个 POST 请求


4. 异步上传 Multipart 文件


    //定义类型
    private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");

    /**
     * 异步上传Multipart文件
     */
    public void sendMultipart() {
        OkHttpClient okHttpClient = new OkHttpClient();

        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("title", "nihao")
                .addFormDataPart("image", "image.jpg", RequestBody.create(MEDIA_TYPE_PNG, new File("/sdcard/image.jpg")))
                .build();

        Request request = new Request.Builder()
                .header("Authorization", "Client-ID " + "...")
                .url("https://api.imgur.com/3/image")
                .post(requestBody)
                .build();

        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.i(TAG, response.body().string());
            }
        });
    }

异步上传文件这种场景在开发中还是很常用的,上传不同类型的文件同时还需要传其他类型的字段,这些用 OkHttp3 实现起来很简单,这里我们只是做了一个示例,实际开发中大家还要具体对应自己的服务器联调


5. 异步下载文件 


    /**
     * 异步下载文件
     *
     * @param view
     */
    public void downFile(View view) {
        OkHttpClient okHttpClient = new OkHttpClient();

        Request request = new Request.Builder().url("下载地址").build();

        okHttpClient.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/iamge.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) {
                    Log.i(TAG, "IOException");
                    e.printStackTrace();
                }

                Log.d(TAG, "文件下载成功");
            }
        });
    }


6. 设置超时时间和缓存


 	File sdcache = getExternalCacheDir();
        int cacheSize = 10 * 1024 * 1024;
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .connectTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(20, TimeUnit.SECONDS)
                .readTimeout(20, TimeUnit.SECONDS)
                .cache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
        OkHttpClient okHttpClient=builder.build();

       这里需要注意得是和 OkHttp2.x 不同的是,不能通过 OkHttpClient 直接设置超时和缓存了,而是通过 OkHttpClient.Builder 来设置,通过 builder 配置好 OkHttpClient 后用 builder.builder() 来返回 OkHttpClient


       我们用到的大概也就这些了,都是一些比较基本的用法,在实际项目中,大家肯定还得进行进一步的封装,要不这样使用大家也看到了,怪累,今天就写到这里,有错误的地方请指出


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值