okhttp学习笔记(使用方法)

1.  创建一个OkHttpClient对象,该对象:
    构造方法:OkHttpClient client = new OkHttpClient();
    如果要添加拦截器,超时等,调用如下构造方法:
        okHttpClient client = new OkHttpClient
                .Builder()
                .readTimeout(int SECONDS,TimeUnit.SECONDS)//设置读取超时时间
                .writeTimeout(int SECONDS,TimeUnit.SECONDS)//设置写的超时时间
                .connectTimeout(int SECONDS,TimeUnit.SECONDS)//设置连接超时时间
                .addInterceptor(appInterceptor)//Application拦截器
                .addNetworkInterceptor(networkInterceptor)//Network拦截器
                .build();


2.  如果网络请求需要请求体,则需要创建一个RequestBody对象,
    RequestBody是一个抽象类,API提供的实现类主要有MultipartBody上传文件和FormBody上传表单两个
        FormBody源码中使用两个链表存储键值对,构造方法如下:
        RequestBody requestBody = new FormBody.Builder
                                .add(String name, String value)
                                .add(String name, String value)
                                ...
                                .build();
        
        MultipartBody利用静态内部类Part封装请求头(Headers,可以为空)和请求体(RequestBody),
        其构造方法为private,提供静态方法获取Part实例 
        Part提供的静态方法有:
                        create(RequestBody body)
                        create(@Nullable Headers headers, RequestBody body)
                        createFormData(String name, String value)
                        createFormData(String name, @Nullable String filename, RequestBody body)
        
        MultipartBody利用List parts = new ArrayList<>()存放多个Part,
        每个Part封装了一个RequestBody
        MultipartBody利用静态内部类Builder来创建MultipartBody,和向parts列表中添加Part。
        MultipartBody.Builder中的方法有:
                        addPart(Part part)//其他几个静态方法都将调用此方法
                        addPart(RequestBody body)//方法内部将RequestBody对象封装成headers为空的Part对象
                        addPart(@Nullable Headers headers, RequestBody body)
                        addFormDataPart(String name, String value)//添加表单
                        addFormDataPart(String name, @Nullable String filename, RequestBody body)
        最后MultipartBody.Builder通过build()方法返回MultipartBody对象。
        使用示例:
        MultipartBody multipartBody =new MultipartBody.Builder()
                                        .setType(MultipartBody.FORM)
                                        .addFormDataPart("groupId",""+groupId)//添加键值对参数
                                        .addFormDataPart("title","title")
                                        .addFormDataPart("file",file.getName(),RequestBody.create(MediaType.parse("file/*"), file)
                                        .build();


    也可以利用RequestBody中的静态方法create(final @Nullable MediaType contentType, content)创建出RequestBody,
    create()方法中利用匿名内部类实现了RequestBody,其中content可以是String,byte[],File。  
        ps:使用byte[]时可以传入一个int型变量作为偏移量,一个int型变量作为发送量,
        方法原型:
            create(final @Nullable MediaType contentType, final byte[] content,final int offset, final int byteCount)
        示例:          
                MediaType JSON = MediaType.parse("application/json; charset=utf-8");//数据类型为json格式,
                String jsonStr = "{\"username\":\"lisi\",\"nickname\":\"李四\"}";//json数据.
                RequestBody body = RequestBody.create(JSON, josnStr);
    最后还能继承RequestBody创建自己的实现类,该类有三个方法要重写:
                public @Nullable MediaType contentType() {}
                public long contentLength() throws IOException {}
                public void writeTo(BufferedSink sink) throws IOException
                 {sink.write(content);}//BufferedSink是okhttp通信包中的类,该类使用类似java的输出流
    自定义的RequestBody可以实现流的上传


3.  创建一个Request对象,该对象中封装网络请求的参数:
    url(网址)
    method(POST,GET等)
            如果是"GET","HEAD"则不能有请求体
            POST,PUT,PATCH,PROPPATCH,REPORT要有请求体。默认是"GET"
    headers(请求头,以键值对的形式存储)。
    RequestBody(请求体)
    构造方法:Request request = new Request.Builder()
                                        .url(String url)
                                        .addHeader(String name, String value)
                                        .removeHeader(String name)
                                        .method(String method, @Nullable RequestBody body)
                                        .build();

        如果是发送post请求,可以直接把 .method(String method, @Nullable RequestBody body)换成.post(RequestBody body)
        如果是发送get请求,可以直接把  .method(String method, @Nullable RequestBody body)换成.post()
        类似的,其他请求也可以这样设置 .head(),delete(@Nullable RequestBody body),delete(),.put(RequestBody body)等
        该类就是存参数的。


4.  创建一个Call对象
    构造方法:Call call = client.newCall(request);


5.  利用Call对象发出网络请求,获取服务器的回复(封装在Response对象中),发出网络请求有两种方式:
    同步方式:
            Response reponse = call.execute();
    异步方式:(测试发现,onResponse()方法并不运行在主线程中)
            call.enqueue(new Callback() 
            {
                 @Override
                public void onFailure(Call call, IOException e) {}
                 @Override
                public void onResponse(Call call, Response response) throws IOException {} //回调的参数中获取Response
            });
    每一个Call对象只能发出一次网络请求,否则会抛出异常,源码中Call设置了executed字段,
    在execute()和enqueue()方法执行时,首先检查和设置此字段,此操作还使用了synchronized关键字保持同步


6.  利用Response对象读出服务器端的返回结果
    Response封装的主要方法如下:
    protocol()//返回http协议,例如:HTTP_1_1
    code()//返回HTTP的状态码,例如404(Not Found)
    isSuccessful()//判断网络请求是否成功,判断依据是ode >= 200 && code < 300
    message()//返回Http的状态信息/** Returns the HTTP status message. */
    body()//获得ResponseBody响应体对象,最重要
    isRedirect()//是否被重定向,判断依据是code
    close()//关闭响应,方法里面调用了body.close(),关闭响应体,关闭流


7.  利用Reponse中的ReponseBody对象获取服务器代码返回的内容
    MediaType contentType()//获取媒体类型,可能为null
    contentLength()//内容长度
    InputStream byteStream()//获取输入流,文件传输的重要方法
    byte[] bytes()//获取返回体的字节数组,但是返回的响应体长度太大会抛出异常
    Reader charStream()//获取java IO的Reader对象
    String string()//获取响应体中的字符串
    Charset charset()//获取编码的字符集,只有utf-8
    void close()//关闭输入流


8.  拦截器的使用:
    实现Interceptor接口,该接口只用Response intercept(Chain chain)方法需要实现,
    在该方法中调用Chain对象的Response proceed(Request request)方法将请求传到下一个拦截器,
    同时会收到网络请求的响应,处理该响应即可。
    拦截器使用的核心在与Chain对象
    利用Chain中的Request request()方法可以获取原始的请求对象,然后修改请求,例如:修改Request中的统一的参数编码,
    利用Chain中的Response proceed(Request request)修改获取响应,将响应统一修改后再返回给上层的拦截器

你可能感兴趣的:(android)