OkHttp基础讲解

一.简介

在Android项目开发中使用HTTP协议完成与服务器通信的话,OkHttp是最常用的框架。OkHttp是一个高效的HTTP客户端,是目前Android使用最广泛的网络框架。它有几个优点。

<1> 支持Http1、Http2、Quic以及WebSocket。

<2> 连接池复用底层TCP(Socket) 减少请求延时。

<3> 无缝的支持GZIP减少数据流量。

<4> 缓存响应数据减少重复的网络请求。

<5> 请求失败自动重试主机的其他ip,自动重定向。

二.代码实现

1.Gradle依赖

implementation 'com.squareup.okhttp3:okhttp:3.9.0'

2.Get&Post请求

package com.wjn.networkdemo.okhttp.only;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.wjn.networkdemo.R;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class OkHttpOnlyActivity extends AppCompatActivity {

    private TextView textView1;
    private TextView textView2;
    private String getUrl = "http://fanyi.youdao.com/openapi.do?keyfrom=imoocdict123456&key=324273592&type=data&doctype=json&version=1.1&q=blue";
    private String postUrl = "http://fanyi.youdao.com/openapi.do";

    private OkHttpClient mOkHttpClient = null;//OkHttpClient 对象

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_okhttp_only);

        textView1 = findViewById(R.id.activity_okhttp_only_textview1);
        textView2 = findViewById(R.id.activity_okhttp_only_textview2);

        //创建OkHttpClient对象
        mOkHttpClient = new OkHttpClient.Builder()
                .connectTimeout(20, TimeUnit.SECONDS)//连接时间
                .readTimeout(20, TimeUnit.SECONDS)//读时间
                .writeTimeout(20, TimeUnit.SECONDS)//写时间
                .retryOnConnectionFailure(true)//连接失败后是否重新连接
                .build();


        textView1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getData();
            }
        });

        textView2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Map<String, String> params = new HashMap<>();
                params.put("keyfrom", "imoocdict123456");
                params.put("key", "324273592");
                params.put("type", "data");
                params.put("doctype", "json");
                params.put("version", "1.1");
                params.put("q", "red");
                postData(params);
            }
        });

    }

    /**
     * OkHttp Get请求
     */

    private void getData() {
        //1.创建Request对象 构建一个具体的网络请求对象 包括具体的请求url&请求头&请求体等等
        Request request = new Request.Builder().url(getUrl).get().build();
        //2.获取Call对象 将具体的网络请求与执行请求的实体进行绑定,形成一个具体的正式的可执行实体
        Call call = mOkHttpClient.newCall(request);
        //3.Call对象进行网络请求 enqueue异步  execute同步一般不用
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d("OkHttpOnlyActivity", "Get请求 onFailure方法执行 错误信息----:" + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (null != response && response.isSuccessful()) {
                    Log.d("OkHttpOnlyActivity", "Get请求 onResponse方法执行报文----:" + response.body().string());
                }
            }
        });
    }

    /**
     * OkHttp Post请求
     */

    private void postData(final Map<String, String> params) {
        //1.获取FormBody.Builder对象
        FormBody.Builder builder = new FormBody.Builder();
        //2.遍历params 将其放入到FormBody.Builder 对象
        if (params != null && !params.isEmpty()) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.add(entry.getKey(), entry.getValue());
            }
        }
        //3.获取RequestBody 对象
        RequestBody requestBody = builder.build();
        //4.创建Request对象 构建一个具体的网络请求对象 包括具体的请求url&请求头&请求体等等
        Request request = new Request.Builder().url(postUrl).post(requestBody).build();
        //5.获取Call对象 将具体的网络请求与执行请求的实体进行绑定,形成一个具体的正式的可执行实体
        Call call = mOkHttpClient.newCall(request);
        //6.Call对象进行网络请求 enqueue异步  execute同步一般不用
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d("OkHttpOnlyActivity", "Post请求 onFailure方法执行 错误信息----:" + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (null != response && response.isSuccessful()) {
                    Log.d("OkHttpOnlyActivity", "Post请求 onResponse方法执行报文----:" + response.body().string());
                }
            }
        });
    }

}

3.结果

<1> Get请求

D/OkHttpOnlyActivity: Get请求 onResponse方法执行报文----:{"translation":["蓝色的"],"basic":{"us-phonetic":"bluː","phonetic":"bluː","uk-phonetic":"bluː","explains":["adj. 蓝色的;忧郁的,悲观的;(由于冷或呼吸困难)发青的,青紫的;(电影、玩笑或故事)色情的,黄色的;(肉)未熟的;(政治上)保守的","n. 蓝色;蓝色物品;(牛津或剑桥大学的运动员)蓝色荣誉者;失误;红发人;打架","vt. (使)变成蓝色;把......染成蓝色;给\u2026\u2026上蓝色漂白剂;挥霍(钱财)","n. (Blue) (英、美、加、澳、新)布卢(人名)"]},"query":"blue","errorCode":0,"web":[{"value":["蓝色的","刀枪不入","蓝色橙味糖浆"],"key":"blue"},{"value":["蓝月","蓝月亮","千载难逢的时机"],"key":"Blue Moon"},{"value":["青尼罗省","青尼罗河","蓝色尼罗河"],"key":"Blue Nile"}]}

<2> Post请求

D/OkHttpOnlyActivity: Post请求 onResponse方法执行报文----:{"translation":["红色的"],"basic":{"us-phonetic":"red","phonetic":"red","uk-phonetic":"red","explains":["adj. 红的,红色的;(毛发)红褐色的;(脸)涨红的;(眼睛)红肿的;革命的,激进的;(人)红种的;(纸牌中)红桃的,红方块的;(葡萄酒)红的;(表示停止)红(灯),红(旗);被禁止的,危险的;(滑雪道上用红色标志指示)第二高难度的;(物理)表示夸克三种颜色之一的红色;赤色的(尤指冷战期间用于指前苏联);沾有鲜血的;(古或诗\/文)流血的;(科萨人)来自传统部落文化的","n. 红色,红颜料;红衣;红葡萄酒;红色物(或人);赤字,亏空;激进分子","n. (Red) 雷德(人名)"]},"query":"red","errorCode":0,"web":[{"value":["红","红色","赤焰战场"],"key":"RED"},{"value":["红线","台北捷运红线","红线机油"],"key":"Red Line"},{"value":["红旗","红旗演习","危险信号"],"key":"red flag"}]}

4.补充

<1> OKHTTP请求成功之后在onResponse方法中可以得到一个Response对象

           [1] 如果想获得返回的字符串结果则可以通过response.body().string()

           [2] 如果想获得返回结果的二进制数据的话可以通过response.body().bytes()

           [3] 如果想获得返回的InputStream的话可以通过response.body().byteStream()

且拿各种返回报文时,需要判断Response对象是否为空且是否成功。代码如上。

<2> OkHttp的主角们

[1] OkHttpClient

Factory for calls, which can be used to send HTTP requests and read their responses.
工厂生产者,负责生产calls。

 OkHttpClient mOkHttpClient = new OkHttpClient.Builder()
                .connectTimeout(DataConstant.nettimeout, TimeUnit.SECONDS)//连接时间
                .readTimeout(DataConstant.nettimeout, TimeUnit.SECONDS)//读时间
                .writeTimeout(DataConstant.nettimeout, TimeUnit.SECONDS)//写时间
                .build();

[2] Request

OkHttp的请求,通过Request.Builder().build创建, Request.Builder()配置请求信息,如请求方式get/post等、请求参数RequestBody、请求头header

Request request = new Request.Builder().addHeader("cookie", cookie).url(url).get().build();

[3] Call

调度者,Call作顶级接口,具体实现由RealCall负责。负责RequestResponse的桥梁作用,将Requestexecute()同步的方式执行输出Response, 或将Requestenqueue(callback)异步的方式加入调度。

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

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

<3> OKHttp框架GitHub链接:https://github.com/square/okhttp

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值