OKHTTP

2021-09-11  本文已影响0人  闫鹏飞写字的地方

OKHTTP

引用

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

权限配置

<user_permissions android:name="android.permissions.INTETNET"/>

测试URL

https://www.httpbin.org/

同步请求

        new Thread(new Runnable() {

            @Override
            public void run() {

                OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).build();
                Request request = new Request.Builder().url("https://www.httpbin.org/")
                        .get().build();
                Call call = client.newCall(request);
                try {
                    Response response = call.execute();
                    Log.i(TAG, "response:"+response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

异步请求

        OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).build();
        Request request = new Request.Builder().url("https://www.httpbin.org/")
                .get().build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i("MyTest", "Fail e:"+e.getMessage());
            }

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

异步get请求

public class MainActivity extends AppCompatActivity {

    private String TAG = "MainActivityLog";

    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //测试get请求
        testOkhttpGet();
    }

    /**
     * 测试okhttp的get方法
     */
    private void testOkhttpGet() {
        String url = "http://api.k780.com/?app=weather.history";
        okhttp3.Request request = new okhttp3.Request.Builder().url(url).get().build();
        OkHttpClient okHttpClient = new OkHttpClient();
        final Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Message message = Message.obtain();
                message.what = 0;
                message.obj = e.getMessage();
                mHandler.sendMessage(message);
                Log.d(TAG, "onFailure: " + message.obj.toString());
            }

            @Override
            public void onResponse(Call call, okhttp3.Response response) throws IOException {
                Message message = Message.obtain();
                message.what = 1;
                message.obj = response.body().string();//string不能调用两次 被调用一次就关闭了,这里调用两次会报异常
                mHandler.sendMessage(message);
                Log.d(TAG, "response: " + message.obj.toString());
            }
        });

    }
    
}

异步测试post请求

public class MainActivity extends AppCompatActivity {

    private String TAG = "MainActivityLog";

    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //测试get请求
        testOkhttpPost();
    }

    /**
     * 测试okhttp的post方法
     */
    private void testOkhttpPost() {
        String url = "http://api.k780.com/?app=weather.history";//
        // &weaid=1&date=2018-08-13&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json";

        OkHttpClient okHttpClient = new OkHttpClient();
        RequestBody body = new FormBody.Builder()
                .add("weaid", "1")
                .add("date", "2018-08-13")
                .add("appkey", "10003")
                .add("sign", "b59bc3ef6191eb9f747dd4e83c99f2a4")
                .add("format", "json")
                .build();

        okhttp3.Request request = new okhttp3.Request.Builder()
                .url(url)
                .post(body)
                .build();

        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Message message = Message.obtain();
                message.what = 0;
                message.obj = e.getMessage();
                mHandler.sendMessage(message);
                Log.d(TAG, "response: " + message.obj.toString());
            }

            @Override
            public void onResponse(Call call, okhttp3.Response response) throws IOException {
                Message message = Message.obtain();
                message.what = 1;
                message.obj = response.body().string();//string不能调用两次 被调用一次就关闭了,这里调用两次会报异常
                mHandler.sendMessage(message);
                Log.d(TAG, "response: " + message.obj.toString());
            }
        });

    }
    
}

Retrofit

一:Retrofit是什么?
准确来说,Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。
原因:网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口的封装
我们先来看看下面这个图:

上图说明了如下几点:

  1. App应用程序通过 Retrofit 请求网络,实际上是使用 Retrofit 接口层封装请求参数、Header、Url 等信息,之
    后由 OkHttp 完成后续的请求操作。
  2. 在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit,Retrofit根据用户的需求对结果进行解析。
    所以,网络请求的本质仍旧是OkHttp完成的,retrofit只是帮使用者来进行工作简化的,比如配置网络,处理数据等
    工作,提高这一系列操作的复用性。这也就是网上流行的一个不太准确的总结:okhttp是瑞士军刀,retrofit则是讲这
    边瑞士军刀包装从了一个非常好用的指甲钳。

二: Retrofit 对Okhttp做了什么
Retrofit并没有改变网络请求的本质,也无需改变,因为Okhttp已经足够强大,Retrofit的封装可以说是很强大,里
面涉及到一堆的设计模式,可以通过注解直接配置请求,可以使用不同的http客户端,虽然默认是用http ,可以使用
不同Json Converter 来序列化数据,同时提供对RxJava的支持,使用Retrofit + OkHttp + RxJava 可以说是目前比较
潮的一套框架,但是需要有比较高的门槛。
下面我们来对比一下OKhttp网络请求和 retrofit网络请求的区别。

2.1. Okhttp请求总结
[大家先看下面okhttp请求的样例代码]

private void testOkHttp() throws IOException {
    //Step1
    final OkHttpClient client = new OkHttpClient();
    //Step2
    final Request request = new Request.Builder()
     .url("https://www.google.com.hk").build();
    //Step3
    Call call = client.newCall(request);
    //step4 发送网络请求,获取数据,进行后续处理
    call.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.toString());
          Log.i(TAG,response.body().string());
     }
   });
 }

「解析一下上面的代码」
Step1:创建HttpClient对象,也就是构建一个网络类型的实例,一般会将所有的网络请求使用同一个单例对象。
Step2:构建Request,也就是构建一个具体的网络请求对象,具体的请求url,请求头,请求体等等。
Step3:构建请求Call,也就是将具体的网络请求与执行请求的实体进行绑定,形成一个具体的正式的可执行实体。
Step4: 后面就进行网络请求了,然后处理网络请求的数据了。
「总结一下」
OKhttp的意义:OkHttp 是基于Http协议封装的一套请求客户端,虽然它也可以开线程,但根本上它更偏向真正的
请求,跟HttpClient, HttpUrlConnection的职责是一样的。
Okhttp的职责:OkHttp主要负责socket部分的优化,比如多路复用,buffer缓存,数据压缩等等。
Okhttp给用户留下的问题:
1)用户网络请求的接口配置繁琐,尤其是需要配置请求body,请求头,参数的时候;
2)数据解析过程需要用户手动拿到responsbody进行解析,不能复用;
3)无法适配自动进行线程的切换。
那么这几个问题谁来解决? 对,retrofit!

上一篇 下一篇

猜你喜欢

热点阅读