zoukankan      html  css  js  c++  java
  • 25、AndroidOkHttp

    OkHttp

    OkHttp是一个优秀的网络请求框架,在使用需要添加相应的依赖:

    implementation "com.squareup.okhttp3:okhttp:3.11.0"

    还有请求网络的权限:

    GET请求

    使用OkHttp进行Get请求只需要四步即可完成。

    // 构建OkHttpClient对象
    OkHttpClient client = new OkHttpClient();
    // 构造Request对象
    Request request = new Request.Builder()
          .url("www.baidu.com")
          .get()
          .build();
    //将Request封装为Call
    Call call = client.newCall(request);
    

    最后,根据需要调用同步或者异步请求方法即可

    同步调用

    //同步调用,返回Response,会抛出IO异常
    Response response = call.execute();
    

    异步调用

    //异步调用,并设置回调函数
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Toast.makeText(OkHttpActivity.this, "get failed", Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void onResponse(Call call, final Response response) throws IOException {
            final String res = response.body().string();
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    contentTv.setText(res);
                }
            });
        }
    });
    

    在使用OkHttp需要注意:

    同步调用会阻塞主线程,一般不适用
    异步调用的回调函数是在子线程,需要借助于 runOnUiThread() 方法或者Handler来处理。
    

    POST提交键值对

    使用OkHttp进行Post请求和进行Get请求很类似,只需要五步即可完成。

    // 构建OkHttpClient对象
    OkHttpClient client = new OkHttpClient();
    // 构建FormBody传入参数
    FormBody formBody = new FormBody.Builder()
        .add("username", "admin")
        .add("password", "admin")
        .build();
    // 构造Request对象,将FormBody作为Post方法的参数传入
    Request request = new Request.Builder()
        .url("https:www.baidu.com")
        .post(formBody)
        .build();
    //将Request封装为Call
    Call call = client.newCall(request);
    

    最后,调用请求,重写回调方法:

    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            Toast.makeText(OkHttpActivity.this, "Post Failed", Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            final String res = response.body().string();
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    contentTv.setText(res);
                }
            });
        }
    });
    

    POST提交字符串

    POST提交字符串就需要使用RequestBody,其中FormBody是RequestBody的子类。

    // 构建OkHttpClient对象
    OkHttpClient client = new OkHttpClient();
    // 构建FormBody传入参数
    RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain;charset=utf-8"), "1111111111111111");
    // 构造Request对象,将FormBody作为Post方法的参数传入
    Request request = new Request.Builder()
            .url("www.baidu.com")
            .post(requestBody)
            .build();
    //将Request封装为Call
    Call call = client.newCall(request);
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
        }
    
        @Override
        public void onResponse(Call call, Response response) throws IOException {
        }
    });
    

    上面的MediaType我们指定传输的是纯文本,而且编码方式是utf-8,通过上面的方式我们就可以向服务端发送json字符串。

    POST上传文件

    这里我们以上传一张图片为例,演示OkHttp上传单文件:

    OkHttpClient okHttpClient = new OkHttpClient();
    File file = new File(Environment.getExternalStorageDirectory(), "1.png");
    RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"),file);
    Request request = new Request.Builder()
            .url("www.baidu.com")
            .post(requestBody)
            .build();
    Call call = okHttpClient.newCall(request);
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
        }
    
        @Override
        public void onResponse(Call call, Response response) throws IOException {
        }
    });
    

    如果是多文件上传,可以使用表单的方式来提交:

    List<String> fileNames = new ArrayList<>();
    fileNames.add(Environment.getExternalStorageState() + "/1.png");
    fileNames.add(Environment.getExternalStorageState() + "/2.png");
    OkHttpClient okHttpClient = new OkHttpClient();
    MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
    for (String fileName : fileNames) {
        File file = new File(fileName);
        builder.addFormDataPart("files", file.getName(), RequestBody.create(
                MediaType.parse("multipart/form-data"), file));
    }
    MultipartBody multipartBody = builder.build();
    Request request = new Request.Builder()
            .url("www.baidu.com")
            .post(multipartBody)
            .build();
    Call call = okHttpClient.newCall(request);
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
        }
    
        @Override
        public void onResponse(Call call, Response response) throws IOException {
        }
    });
    

    POST提交表单

    其中,MultipartBody是RequestBody的子类,提交表单需要使用它来构建RequestBody。

    File file = new File(Environment.getExternalStorageDirectory(), "1.png");
    OkHttpClient okHttpClient = new OkHttpClient();
    RequestBody requestBody = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("username", "admin")
            .addFormDataPart("password", "admin")
            .addFormDataPart("file", file.getName(),
                    RequestBody.create(MediaType.parse("application/octet-stream"), file))
            .build();
    Request request = new Request.Builder()
            .url("www.baidu.com")
            .post(requestBody)
            .build();
    Call call = okHttpClient.newCall(request);
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
        }
    
        @Override
        public void onResponse(Call call, Response response) throws IOException {
        }
    });
    

    GET下载文件

    下面将演示OkHttp使用GET请求下载文件的实例:

    OkHttpClient okHttpClient = new OkHttpClient();
    Request request = new Request.Builder()
            .url("www.baidu.com/1.png")
            .get()
            .build();
    Call call = okHttpClient.newCall(request);
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
        }
    
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            InputStream inputStream = response.body().byteStream();
            int len;
            File file  = new File(Environment.getExternalStorageDirectory(), "1.png");
            FileOutputStream fos = new FileOutputStream(file);
            byte[] buf = new byte[128];
    
            while ((len = inputStream.read(buf)) != -1){
                fos.write(buf, 0, len);
            }
            fos.flush();
            fos.close();
            inputStream.close();
        }
    });
    

    可以通过流的读取来实现文件的上传和下载进度显示。

    OkHttp拦截器

    OkHttp的拦截器有五种内置的,除此之外还可以自定义拦截器。

    • retryAndFollowUpInterceptor:重试和重定向拦截器,主要负责网络失败重连。
    • BridgeInterceptor:主要负责添加交易请求头。
    • CacheInterceptor:缓存拦截器,主要负责拦截缓存。
    • ConnectInterceptor:网络连接拦截器,主要负责正式开启http请求。
    • CallServerInterceptor:负责发送网络请求和读取网络响应

    这里主要介绍使用自定义日志拦截器来打印Logger信息。

    1)创建HttpLogger类实现HttpLoggingInterceptor.Logger

    public class HttpLogger implements HttpLoggingInterceptor.Logger {
        @Override
        public void log(String message) {
            Log.e("HttpLogInfo", message);
        }
    }
    

    2) 使用OkHttpClient.Builder添加拦截器

    // Add Logger Interceptor
    HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLogger());
    loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
    clientBuilder.addNetworkInterceptor(loggingInterceptor);
    

    这样,就可以在请求网络的时候看到OkHttp的日志信息。

    关于OkHttp还有很多内容,这里只是简单的介绍使用。

  • 相关阅读:
    jsp grid can not be used in this ('quirks') mode
    weblogic stage更改不马上生效
    shell执行class或jar
    java json字符串与对象转换
    js对象及元素复制拷贝
    js中json字符串与对象的转换及是否为空
    js window.open隐藏参数提交
    poi excel文件名或者内容中文乱码
    linux poi生成excel demo调试附调用代码
    PeekMessage与GetMessage的对比
  • 原文地址:https://www.cnblogs.com/pengjingya/p/14952103.html
Copyright © 2011-2022 走看看