OKHTTP

作者: 闫鹏飞写字的地方 | 来源:发表于2021-09-11 12:02 被阅读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!

    相关文章

      网友评论

          本文标题:OKHTTP

          本文链接:https://www.haomeiwen.com/subject/hbgowltx.html