OkHttp的基本使用

Android常用框架

一、 OkHttp

  • Okhttp是一个高效的http客户端,处理网络请求的开源项目。
Http协议结构
  • 请求头
    • 表明本次请求的客户端
    • 本次请求所使用的Cookie
    • 本次请求希望返回的数据类型
    • 本次请求是否采用数据压缩等一系列设置
  • 请求体
    • 本次请求所使用的方法
    • 主要用来携带本次请求的参数
  • 响应头、
    • 服务器标识
    • 状态码
    • 内容编码
    • Cookie返回给客户端的Cookie等
  • 响应体
    • 本次请求所返回的数据
Http工作流程
  • 首先客户端与服务器简历连接。
  • 建立连接后,客户端发送一个请求给服务器。
  • 服务器接到请求后,给予相应的响应信息。
  • 客户端接收服务器所返回的信息,连接断开。
Http优势
  • 简单,快速,灵活。
  • 无连接,无状态。
SPDY
  • SPDY是一种HTTP的兼容协议。
  • 多路复用请求。
  • 对请求划分优先级。
  • 压缩HTTP头。
HTTP2.0
  • 基于SPDY,IETF定制的新一代HTTP协议。
  • 更安全的SSL。
特性:
  1. 能够高效的执行http,数据加载速度更快,更省流量。
  2. 支持Gzip压缩,提升速度,节省流量。
  3. 缓存响应数据,避免了重复的网络请求。
  4. 使用简单,支持同步阻塞调用和带回调的异步调用。
  5. 支持SPDY,HTTP2.0共享同一个Socket来处理同一个服务器的所有请求。
  6. 如果SPDY不可用,则通过连接池来减少请求延时。
GitHub地址:https://github.com/square/okhttp
依赖: implementation("com.squareup.okhttp3:okhttp:4.1.0")
权限: <uses-permission android:name="android.permission.INTERNET"/>
Get请求:
    //1.创建OkhttpClient对象
    OkHttpClient client = new OkHttpClient();
    //2.创建request对象,设置一个url地址,请求方式
    Request request = new Request.Builder()
            .url("http://www.baidu.com")
            .get()
            .build();
    //3.创建一个call对象,参数就是request对象
    Call call = client.newCall(request);
同步Get请求:
  • 提交同步get请求会阻塞线程,避免ANR异常,需要开启一个子线程。

      new Thread(){
        @Override
          public void run() {
              try {
                  Response response = call.execute();
      			Log.d(TAG, response.body().toString());
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }.start();
    
异步Get请求:
  //4.请求加入回调,重写回调方法
  call.enqueue(new Callback() {
	//请求失败
        @Override
        public void onFailure(Call call, IOException e) {
            Log.d(TAG, "onFailure: "+e.getMessage());
        }
	//请求成功
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            Log.d(TAG, "onResponse: "+response.body().toString());
        }
    });
Post请求:
  • 构造request对象时,需要构造一个RequestBody对象,携带提交的数据。构造时需要指定MediaType,用于描述请求/响应的内容类型。常见类型有:

      text/html:HTML格式
      text/pain:纯文本格式
      image/jpeg:jpg图片格式
      application/json:JSON数据格式	
      application/octet-stream:二进制流数据(如常见的文件下载)
      application/x-www-form-urlencoded:form表单encType属性的默认格式,表单数据将以key/value的形式发送到服务端
      multipart/form-data:表单上传文件的格式
    
  • 上传json字符串

      OkHttpClient client = new OkHttpClient();
      //构造 RequestBody 需要指定MediaType,用于描述请求/响应 body 的内容类型
      MediaType JSON = MediaType.parse("application/json; charset=utf-8");
      String json = "{\"name\":\"zhangsan\",\"age\":\"20\"}";
      new Request.Builder()
              .url(url)
              .post(RequestBody.create(JSON, json))
              .build();
      client.newCall(request).enqueue(new Callback() {
          @Override
          public void onFailure(Call call, IOException e) {
    
          }
          @Override
          public void onResponse(Call call, Response response) throws IOException {
    
          }
      });
    
  • 上传文件

      OkHttpClient client = new OkHttpClient();
      String filePath = "C:\\Users\\yhj\\Desktop\\SoftwareFramework";
      File file = new File(filePath);
      Request request = new Request.Builder()
              .url(url)
              .post(RequestBody.create(MediaType.parse("application/octet-stream"), file))
              .build();
      client.newCall(request).enqueue(new Callback() {
          @Override
          public void onFailure(Call call, IOException e) {
    
          }
    
          @Override
          public void onResponse(Call call, Response response) throws IOException {
    
          }
      });
    
  • 提交表单文件

      OkHttpClient client = new OkHttpClient();
      RequestBody requestBody = new FormBody.Builder()
              .add("name", "value")
              .build();
      Request request = new Request.Builder()
              .url(url)
              .post(requestBody)
              .build();
      client.newCall(request).enqueue(new Callback() {
          @Override
          public void onFailure(Call call, IOException e) {
    
          }
    
          @Override
          public void onResponse(Call call, Response response) throws IOException {
    
          }
      });
    
  • 使用MultipartBody同时上传多种类型数据

      OkHttpClient client = new OkHttpClient();
      String filePath="";
      File file = new File(filePath);
      MultipartBody multipartBody = new MultipartBody.Builder()
      		//设置类型是表单
              .setType(MultipartBody.FORM)
              .addFormDataPart("name", "value")
              .addFormDataPart("name1", "value1")
              .addFormDataPart("name", file.getName(), RequestBody.create(MediaType.parse("application/octet-stream"), file)).build();
      Request request = new Request.Builder()
              .url(url)
              .post(multipartBody)
              .build();
      client.newCall(request).enqueue(new Callback() {
          @Override
          public void onFailure(Call call, IOException e) {
              
          }
    
          @Override
          public void onResponse(Call call, Response response) throws IOException {
    
          }
      });
    
  • 异步下载一个图片文件

      String url="http://pic1.win4000.com/wallpaper/c/53cdd1f7c1f21.jpg";
      OkHttpClient client = new OkHttpClient();
      Request request = new Request.Builder()
              .url(url)
              .get()
              .build();
      client.newCall(request).enqueue(new Callback() {
          @Override
          public void onFailure(Call call, IOException e) {
              Log.d(TAG, "onFailure: "+e.getMessage());
          }
    
          @Override
          public void onResponse(Call call, Response response) throws IOException {
              InputStream inputStream = response.body().byteStream();
              int len=0;
              File file = new File(Environment.getExternalStorageDirectory(), "baidu.jpg");
              FileOutputStream fos = new FileOutputStream(file);
              byte[] bytes = new byte[1024];
              while ((len=inputStream.read(bytes))!=-1){
                  fos.write(bytes);
              }
              fos.flush();
              fos.close();
              inputStream.close();
          }
      });
    
  • 网络下载图片显示到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();
      }
    
  • 设置超时时间和缓存

      OkHttpClient.Builder builder = new OkHttpClient.Builder()
              .writeTimeout(20, java.util.concurrent.TimeUnit.SECONDS)
              .connectTimeout(15, java.util.concurrent.TimeUnit.SECONDS)
              .readTimeout(20,TimeUnit.SECONDS)
              .cache(new Cache(new File("pathname"),1024*1024*100));
      builder.build();
    
  • Http头部的设置和读取

    HTTP 头的数据结构是 Map<String, List<String>>类型。也就是说,对于每个 HTTP 头,可能有多个值。但是大部分 HTTP 头都只有一个值,只有少部分 HTTP 头允许多个值。至于name的取值说明,可以查看这个Http请求头大全

OkHttp的处理方式是:

  • 使用header(name,value)来设置HTTP头的唯一值,如果请求中已经存在响应的信息那么直接替换掉。

  • 使用addHeader(name,value)来补充新值,如果请求头中已经存在name的name-value,那么还会继续添加,请求头中便会存在多个name相同而value不同的“键值对”。

  • 使用header(name)读取唯一值或多个值的最后一个值

  • 使用headers(name)获取所有值

      OkHttpClient client = new OkHttpClient();
      Request request = new Request.Builder()
              .url("https://github.com")
              .header("User-Agent", "My super agent")
              .addHeader("Accept", "text/html")
              .build();
      Response response = client.newCall(request).execute();
      if (!response.isSuccessful()) {
          throw new IOException("服务器端错误: " + response);
      }
      System.out.println(response.header("Server"));
      System.out.println(response.headers("Set-Cookie"));
    

小结: OKHttp是一个处理网络请求的开源项目,Android 当前最火热网络框架,由移动支付Square公司贡献,用于替代HttpUrlConnection和Apache HttpClient(android API23 6.0里已移除HttpClient)。

<think>好的,用户想了解OkHttp3基本使用方法。我需要先回忆一下OkHttp3的主要功能常见用途。OkHttp是一个广泛使用的HTTP客户端库,适用于AndroidJava应用程序,用于处理网络请求。用户可能是个刚入门的开发者,需要快速上手,所以回答要简明扼要,步骤清晰。 首先,我应该介绍如何引入OkHttp3的依赖,比如在Gradle中添加依赖项。然后,可能需要分几个部分,比如同步请求、异步请求POST请求、拦截器等常见用法。用户可能关心的是基本使用,不需要太深入的高级功能,但适当提一下拦截器可以展示其扩展性。 需要注意OkHttp3基本请求流程:创建OkHttpClient实例,构建Request对象,调用newCall方法执行请求,处理响应。同步异步的区别需要明确说明,同步请求需要在子线程执行,而异步请求通过回调处理结果。 POST请求部分,用户可能需要知道如何提交表单数据JSON数据,这里要给出具体的示例代码,比如使用FormBodyRequestBody。此外,文件上传作为POST的一个常见场景,也应该包含进去,但要注意代码的正确性,比如正确的MIME类型MultipartBody的构建。 拦截器部分可以简要说明其用途,比如添加日志或修改请求头,给出一个日志拦截器的例子,这样用户能直观了解如何自定义拦截器。 最后,可能还需要提醒一些注意事项,比如网络权限的添加,在Android中需要在Manifest文件里声明INTERNET权限。此外,提到响应处理时的异常捕获,比如IOException,确保应用的健壮性。 需要检查代码示例是否正确,比如同步请求的execute()方法会阻塞线程,必须放在子线程中执行,而异步请求的enqueue方法会自动在后台线程执行回调。POST请求的MediaType是否正确,特别是JSON的application/json类型是否正确使用。 可能用户在实际使用中会遇到问题,比如依赖无法下载,需要确认是否使用了正确的仓库,或者版本号是否最新。但用户的问题主要是基本使用,所以这些细节可能暂时不需要深入,除非用户后续追问。 总之,结构要清晰,分点说明,代码示例正确且关键部分有注释,注意事项也要提到,帮助用户避免常见错误。确保回答简洁,但覆盖主要的使用场景,让用户能快速上手OkHttp3基本操作。</think>以下为OkHttp3基本使用方法核心步骤: ----- ### 一、添加依赖 ```gradle // Gradle配置 implementation &#39;com.squareup.okhttp3:okhttp:4.9.3&#39; // 使用最新版本 ``` ----- ### 二、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常用操作,实际开发中可根据需求组合使用这些功能模块。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

八归少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值