OkHttp的基本使用

OKhttp的post请求和get请求

  • 提交键值对
        //1.创建OkHttpClient对象
        OkHttpClient  okHttpClient = new OkHttpClient();
        //2.通过new FormBody()调用build方法,创建一个RequestBody,可以用add添加键值对 
        RequestBody  requestBody = new FormBody.Builder().add("name","zhangqilu").add("age","25").build();
        //3.创建Request对象,设置URL地址,将RequestBody作为post方法的参数传入
        Request request = new Request.Builder().url("url").post(requestBody).build();
        //4.创建一个call对象,参数就是Request请求对象
        Call call = okHttpClient.newCall(request);
        //5.请求加入调度,重写回调方法
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
            }
        });
  • 提交字符串
 MediaType mediaType = MediaType.parse("application/json; charset=utf-8");//"类型,字节码"
        //字符串
        String value = "{username:admin;password:admin}"; 
        //1.创建OkHttpClient对象
        OkHttpClient  okHttpClient = new OkHttpClient();
        //2.通过RequestBody.create 创建requestBody对象
        RequestBody requestBody =RequestBody.create(mediaType, value);
        //3.创建Request对象,设置URL地址,将RequestBody作为post方法的参数传入
        Request request = new Request.Builder().url("url").post(requestBody).build();
        //4.创建一个call对象,参数就是Request请求对象
        Call call = okHttpClient.newCall(request);
        //5.请求加入调度,重写回调方法
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
            }
        });
  • 异步post请求上传文件
    首先添加存储卡读写权限,在AndroidManifest.xml文件中添加如下代码:
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

具体代码:

        //1.创建OkHttpClient对象
        OkHttpClient  okHttpClient = new OkHttpClient();
        //上传的图片
        File file = new File(Environment.getExternalStorageDirectory(), "zhuangqilu.png");
        //2.通过RequestBody.create 创建requestBody对象,application/octet-stream 表示文件是任意二进制数据流
        RequestBody requestBody =RequestBody.create(MediaType.parse("application/octet-stream"), file);
        //3.创建Request对象,设置URL地址,将RequestBody作为post方法的参数传入
        Request request = new Request.Builder().url("url").post(requestBody).build();
        //4.创建一个call对象,参数就是Request请求对象
        Call call = okHttpClient.newCall(request);
        //5.请求加入调度,重写回调方法
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
            }
        });
  • 异步get请求下载文件
 //1.创建OkHttpClient对象
        OkHttpClient okHttpClient = new OkHttpClient();
        //2.创建Request对象,设置一个url地址(百度地址),设置请求方式。
        Request request = new Request.Builder().url("https://www.baidu.com/img/bd_logo1.png").get().build();
        //3.创建一个call对象,参数就是Request请求对象
        Call call = okHttpClient.newCall(request);
        //4.请求加入调度,重写回调方法
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e(TAG, "onFailure: "+call.toString() );
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //拿到字节流
                InputStream is = response.body().byteStream();
                int len = 0;
                //设置下载图片存储路径和名称
                File file = new File(Environment.getExternalStorageDirectory(),"baidu.png");
                FileOutputStream fos = new FileOutputStream(file);
                byte[] buf = new byte[128];
                while((len = is.read(buf))!= -1){
                    fos.write(buf,0,len);
                    Log.e(TAG, "onResponse: "+len );
                }
                fos.flush();
                fos.close();
                is.close();
            }
        });

Get请求下载文件还是比较简单,设置下载地址,在回调函数中拿到了图片的字节流,然后保存为了本地的一张图片。

从网络下载一张图片并直接设置到ImageView中。

@Override
public void onResponse(Call call, Response response) throws IOException {
    InputStream is = response.body().byteStream();
    //使用 BitmapFactory 的 decodeStream 将图片的输入流直接转换为 Bitmap 
    final Bitmap bitmap = BitmapFactory.decodeStream(is);
    //在主线程中操作UI
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            //然后将Bitmap设置到 ImageView 中
            imageView.setImageBitmap(bitmap);
        }
    });

    is.close();
}

OkHttp与http请求

http协议请求消息体分为4部分:请求行(请求方法、请求地址、请求协议)、请求头部、空行和请求数据。也就是说要完成http请求,需要包含请求方法、请求地址、请求协议、请求头、请求体五部分

public final class Request {
  final HttpUrl url; //请求地址
  final String method;//请求方法
  final Headers headers;//请求头
  final RequestBody body; //请求体
  final Object tag;
  ...
}

注:没有请求协议,根据服务器支持哪种协议(Http/1.1 Http/2),就选择哪种协议(Upgrade 机制)

OkHttp与http响应

响应消息分为4部分:状态行(访问协议、响应码、描述信息)、响应头、空行和响应正文(响应体)

public final class Response implements Closeable {
  final Request request; //持有的请求 
  final Protocol protocol; //请求协议
  final int code; //响应码
  final String message; //描述信息
  final Handshake handshake;//代表SSL/TLS握手协议验证时的信息
  final Headers headers;
  final ResponseBody body; //响应体
  final Response networkResponse;
  final Response cacheResponse;
  final Response priorResponse;
  final long sentRequestAtMillis;
  final long receivedResponseAtMillis;
  ...
}

注:response.body().string()只能调用一次,在第一次是有返回值,第二次调用就会返回null。原因:response.body().string()的本质是输入流的读操作,必须有服务器的输出流的写操作时客户端的读操作才能得到数据。而服务器的写操作只执行一次,所以客户端的读操作也只能执行一次,第二次将返回null。

单例的OKHttpClient会不会影响OkHttpClient的扩展性

不会,我们之所以要单例一个OKHttpClient,是应该不重复创建连接池和线程池
也就是说,可以全局定义一个OkHttpClient ,在需要特殊配置一个OKHttpClient的时候,这个局部的OKHttpClient
引用的连接池和线程池是复用自全局单例的就行;
如:

    OkHttpClient eagerClient = client.newBuilder()
        .readTimeout(500, TimeUnit.MILLISECONDS)
        .build();
    Response response = eagerClient.newCall(request).execute();

具体实现是:通过全局的OkHttpClient 单例new属性一样的的Builder,然后给这个Builder单独配置局部的属性
后,再通过这个Builder创建一个局部的OKHttpClient即可。

  public Builder newBuilder() {
    return new Builder(this);
  }

  Builder(OkHttpClient okHttpClient) {
      this.dispatcher = okHttpClient.dispatcher;
      this.proxy = okHttpClient.proxy;
       //省略代码

  }

<think>好的,用户想了解OkHttp3的基本使用方法。我需要先回忆一下OkHttp3的主要功能和常见用途。OkHttp一个广泛使用的HTTP客户端库,适用于Android和Java应用程序,用于处理网络请求。用户可能是个刚入门的开发者,需要快速上手,所以回答要简明扼要,步骤清晰。 首先,我应该介绍如何引入OkHttp3的依赖,比如在Gradle中添加依赖项。然后,可能需要分几个部分,比如同步请求、异步请求、POST请求、拦截器等常见用法。用户可能关心的是基本使用,不需要太深入的高级功能,但适当提一下拦截器可以展示其扩展性。 需要注意OkHttp3的基本请求流程:创建OkHttpClient实例,构建Request对象,调用newCall方法执行请求,处理响应。同步和异步的区别需要明确说明,同步请求需要在子线程执行,而异步请求通过回调处理结果。 POST请求部分,用户可能需要知道如何提交表单数据和JSON数据,这里要给出具体的示例代码,比如使用FormBody和RequestBody。此外,文件上传作为POST的一个常见场景,也应该包含进去,但要注意代码的正确性,比如正确的MIME类型和MultipartBody的构建。 拦截器部分可以简要说明其用途,比如添加日志或修改请求头,给出一个日志拦截器的例子,这样用户能直观了解如何自定义拦截器。 最后,可能还需要提醒一些注意事项,比如网络权限的添加,在Android中需要在Manifest文件里声明INTERNET权限。此外,提到响应处理时的异常捕获,比如IOException,确保应用的健壮性。 需要检查代码示例是否正确,比如同步请求的execute()方法会阻塞线程,必须放在子线程中执行,而异步请求的enqueue方法会自动在后台线程执行回调。POST请求的MediaType是否正确,特别是JSON的application/json类型是否正确使用。 可能用户在实际使用中会遇到问题,比如依赖无法下载,需要确认是否使用了正确的仓库,或者版本号是否最新。但用户的问题主要是基本使用,所以这些细节可能暂时不需要深入,除非用户后续追问。 总之,结构要清晰,分点说明,代码示例正确且关键部分有注释,注意事项也要提到,帮助用户避免常见错误。确保回答简洁,但覆盖主要的使用场景,让用户能快速上手OkHttp3的基本操作。</think>以下为OkHttp3的基本使用方法和核心步骤: ----- ### 一、添加依赖 ```gradle // Gradle配置 implementation 'com.squareup.okhttp3:okhttp:4.9.3' // 使用最新版本 ``` ----- ### 二、GET请求 #### 同步请求 ```java OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://api.example.com/data") .build(); try (Response response = client.newCall(request).execute()) { if (response.isSuccessful()) { String result = response.body().string(); System.out.println(result); } } catch (IOException e) { e.printStackTrace(); } // 注意:同步请求需在子线程执行 ``` #### 异步请求 ```java client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { String result = response.body().string(); System.out.println(result); } } }); ``` ----- ### 三、POST请求 #### 表单提交 ```java RequestBody formBody = new FormBody.Builder() .add("username", "admin") .add("password", "123456") .build(); Request request = new Request.Builder() .url("https://api.example.com/login") .post(formBody) .build(); ``` #### JSON提交 ```java MediaType JSON = MediaType.parse("application/json; charset=utf-8"); String json = "{\"name\":\"Alice\",\"age\":25}"; RequestBody body = RequestBody.create(json, JSON); Request request = new Request.Builder() .url("https://api.example.com/users") .post(body) .build(); ``` ----- ### 四、文件上传 ```java File file = new File("/sdcard/image.jpg"); RequestBody fileBody = RequestBody.create(file, MediaType.parse("image/jpeg")); RequestBody multipartBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("file", "avatar.jpg", fileBody) .addFormDataPart("description", "用户头像") .build(); Request request = new Request.Builder() .url("https://api.example.com/upload") .post(multipartBody) .build(); ``` ----- ### 五、拦截器使用 ```java // 添加日志拦截器 OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)) .build(); // 自定义拦截器(示例:添加公共请求头) .addInterceptor(chain -> { Request original = chain.request(); Request newRequest = original.newBuilder() .header("Authorization", "Bearer token123") .build(); return chain.proceed(newRequest); }) ``` ----- ### 注意事项 1. Android应用需添加网络权限: ```xml <uses-permission android:name="android.permission.INTERNET"/> ``` 2. 响应体处理完成后必须关闭: ```java try (ResponseBody body = response.body()) { String result = body.string(); } ``` 3. 文件上传时注意处理大文件的分块传输 以上为OkHttp3的常用操作,实际开发中可根据需求组合使用这些功能模块。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值