OkHttp基础学习(一),Get请求

作者: 英勇青铜5 | 来源:发表于2017-01-06 19:22 被阅读1620次

    学习资料:

    打算花段时间,系统性的学习下OkHttp相关知识。计划先从最简单的get请求学起


    1. Get请求

    运行结果

    网络请求接口来自易源-美女图片


    1.1 GetActivity代码

    布局:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/activity_get"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <TextView
                android:id="@+id/get_activity_tv_show"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:textAllCaps="false"
                android:textColor="@color/colorAccent"
                android:textSize="15sp" />
        </android.support.v4.widget.NestedScrollView>
    
    </RelativeLayout>
    

    直接将TextView放在一个NestScrollView


    OKHttp使用需要3个对象:

    1. OkHttpClient
    2. Request
    3. Call

    Activity代码

    public class GetActivity extends AppCompatActivity implements ResultCallback<String> {
        private TextView tv_info;
        private Platform mPlatform;//平台对象,内部最终调用 , handler.post(runnable)
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_get);
            //得到 Platform  对象
            mPlatform = Platform.get();
            initView();
        }
    
        private void initView() {
            tv_info = (TextView) findViewById(R.id.get_activity_tv_show);
            request();
        }
    
        /**
         * 请求网络
         */
        private void request() {
            //创建OkHttpClient 设置超时时间为10s
            OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS).build();
            //创建Request
            Request request = new Request.Builder().get().url(Urls.GET_URL).build();
            //创建Call
            Call call = okHttpClient.newCall(request);
            //异步执行请求
            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    sendFailResultCallback(e);//失败回调
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    //请求结果
                    ResponseBody responseBody = null;
                    try {
                        //判断请求是否取消
                        if (call.isCanceled()) {
                            sendFailResultCallback(new IOException("Request Canceled"));
                            return;
                        }
                        //获取请求结果 ResponseBody
                        responseBody = response.body();
                        //获取字符串
                        String json = responseBody.string();
                        Log.e("activity", json);
                        //成功回调
                        sendSuccessResultCallback(json);
                    } catch (Exception e) {//发生异常,失败回调
                        sendFailResultCallback(e);
                    } finally {//记得关闭操作
                        if (null != responseBody) {
                            responseBody.close();
                        }
                    }
                }
            });
        }
    
        /**
         * 失败回调接口方法
         */
    
        @Override
        public void sendFailResultCallback(final Exception e) {
            mPlatform.execute(new Runnable() {
                @Override
                public void run() {
                    String info = "Fail Message --> " + e.getMessage();
                    tv_info.setText(info);
                }
            });
        }
    
        /**
         * 成功回调方法
         */
    
        @Override
        public void sendSuccessResultCallback(final String result) {
            mPlatform.execute(new Runnable() {
                @Override
                public void run() {
                    tv_info.setText(JsonFormatUtils.formatJson(result));
                }
            });
        }
    }
    

    call.execute()是同步请求,主线程中无法进行网络请求,需要使用异步call.enqueue()方法

    由于网络请求在子线程中,不能更新UI,考虑结合使用HandlerGetActivity中,并没有直接创建出来一个Handler来使用,而是利用了一个Platform对象,在onCreat()方法中,mPlatform = Platform.get()


    1.2 ResultCallback

    不明白为啥一开始就想到先写个接口。。。写了就写了吧

    public interface ResultCallback <T>{
        //失败时
        void sendFailResultCallback(Exception e);
        //成功时
        void sendSuccessResultCallback(T t);
    }
    

    1.3 Platform

    之前看鸿洋大神的Android 一个改善的okHttp封装库,在代码里面看到的这个类

    代码中有句注释 Copyright (C) 2013 Square, Inc.,说明源自Square公司,在Retrofit源码中也有用到,就学习下怎么使用

    Platform代码

     public class Platform {
        private static final Platform PLATFORM = findPlatform();
    
        public static Platform get() {
            return PLATFORM;
        }
    
        private static Platform findPlatform() {
            try {
                Class.forName("android.os.Build");
                if (Build.VERSION.SDK_INT != 0) {
                    return new Android();
                }
            } catch (ClassNotFoundException ignored) {
                ignored.printStackTrace();
            }
            return new Platform();
        }
    
        public Executor defaultCallbackExecutor() {
            return Executors.newCachedThreadPool();
        }
    
        public void execute(Runnable runnable) {
            defaultCallbackExecutor().execute(runnable);
        }
    
    
        static class Android extends Platform {
            @Override
            public Executor defaultCallbackExecutor() {
                return new MainThreadExecutor();
            }
    
            static class MainThreadExecutor implements Executor {
                private final Handler handler = new Handler(Looper.getMainLooper());
    
                @Override
                public void execute(Runnable r) {
                    handler.post(r);
                }
            }
        }
    }
    

    使用很简单

     mPlatform.execute(new Runnable() {
          //UI线程
          do something 。。。
     }
    

    这段代码感觉可以拿来加深理解 多态


    mPlatform = Platform.get(),在findPlatform()方法中,正常情况,返回的new Android()对象,实际是通过new Android(),得到了Platform的子类Android的一个对象

    之后的mPlatform.execute(),其实就是子类Android直接调用父类Platform中的execute()方法

    然而在execute()方法中,调用了defaultCallbackExecutor()

    Platform中的defaultCallbackExecutor()方法:

    public Executor defaultCallbackExecutor() {
        return Executors.newCachedThreadPool();
    }
    

    通过newCachedThreadPool(),创建出一个默认的缓存线程池


    子类Android中,重写了defaultCallbackExecutor()方法

        @Override
       public Executor defaultCallbackExecutor() {
           return new MainThreadExecutor();
       }
    

    自定义了一个MainThreadExecutor,内部便是对Handler的回调,这个Handler是通过new Handler(Looper.getMainLooper())创建出来的一个UI主线程的Handler,也就可以直接用来更新UI

    mPlatform.execute(Runnbale)正常情况下,最终会被Handler回调

    这段代码的质量明显比上面GetActivity的代码高N条街,Square公司的,不高才怪。GetActivity中,我多此一举的写了个接口

    多学习,以后我也要敲出这样高质量的代码,哈哈 :)


    2. 最后

    最简单的异步get请求,下篇接着学习post请求,文件上传下载之类的

    有错误请指出

    共勉 :)

    相关文章

      网友评论

        本文标题:OkHttp基础学习(一),Get请求

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