【okhttp】小问题记录合集

can’t create native thread

问题描述

OkHttpClient 每次使用都new创建,造成OOM,提示can’t create native thread…

问题分析
没有将OkHttpClient单例化.
每个client对象都有自己的线程池和连接池,如果为每个请求都创建一个client对象,自然会出现内存溢出。所以官方建议OkHttpClient应该单例化,重用连接和线程能降低延迟和减少内存消耗。

问题解决

使用官方推荐的方式,按需创建实例。

  1. new OkHttpClient()
    该方式将创建一个使用默认设置的client单例对象。
  2. new OkHttpClient.Builder()
    该方式允许自定义配置自己的单例client对象。配置connectionTimeout, readTimeout, writeTimeout等参数。
     okHttpClient = new OkHttpClient.Builder()
                            .connectTimeout(50L, TimeUnit.SECONDS)
                            .readTimeout(60L, TimeUnit.SECONDS)
                            .build();
    
    
  3. okHttpclient.newBuilder()
    该方式通过已经存在的client对象,创建特殊需要的client对象。如 我们通过上个方法创建了自定义配置的单例client对象,但是针对某些场景需要调整某些参数,那么就需要使用该方法创建定制的client。新client对象与旧client对象共享连接池,线程池和其他配置。
    OkHttpClient myClient = okHttpClient.newBuilder()
                            .readTimeout(80L, TimeUnit.SECONDS).build();
    
    

get不支持请求体

问题描述

使用Retrofit发送get请求,自定义的service传递了实体bean对象,出现cras

@HTTP(method = "GET",path = "extend-web/intelligence-recipe/queryByModel",hasBody = true)
Call<CookResponse> postCookBook(@Body CookBookRequestBean cookBook);

问题分析

Retrofit自带的Okhttp内部报的错,主要原因是在HttpMethod#permitsRequestBody,判断get方法是否包含请求体,如果包含,就抛出异常;所以get请求发不出去。
Retrofit自带的okhttp不支持带body的get,想跳过那句请求体检查,可以通过修改源码方式解除判断;
Http协议只支持get请求path形式访问,不支持get请求带请求体的,所以即使你修改Okhttp源码,解除了get方法判断是否包含请求体,,也无法从应用层-…—网络层-链路层一层一层的将参数传递到server,更别说进入Tomcat,让Spring框架解析你的参数了;

一句话总结:Http协议规定get请求只能path形式进行查询;Retrofit+Okhttp遵循了Http协议规范,所以抛出异常,强制开发者使用Post协议发请求体。

问题解决

  1. get不传递请求体
  2. 修改body源码,在okhttp组装的时候用post格式组装,发出请
<think>好的,我现在需要回答用户关于OkHttp库的用法和示例的问题。首先,根据用户提供的系统级指令,我需要确保所有行内数学表达式使用$...$格式,独立公式用$$...$$,同时保持LaTeX语法正确,用中文回答,生成相关问题,并在引用部分添加标识。用户还提到参考了站内的引用[1]和[2],但看起来引用[1]是关于OkHttp与Volley、Retrofit的关系以及其特性,而引用[2]是关于Hadoop配置的内容,可能与当前问题无关,所以可能只需要引用[1]。 首先,我需要介绍OkHttp的基本信息,包括它的功能和优势,比如SPDY支持、连接池、磁盘缓存、透明压缩,以及通过Okio支持Java NIO,这些在引用[1]里都有提到。然后,我需要分步骤讲解如何使用OkHttp,比如添加依赖、创建客户端实例、同步和异步请求的示例代码,以及常见的配置项如超时设置、拦截器、缓存和Cookie管理。示例代码需要正确展示GET和POST请求的实现,同步和异步的区别,并且代码块要使用正确的语法高亮。 接下来,生成相关问题,可能涉及OkHttp的底层原理、与Retrofit的比较、性能优化方法以及文件上传的实现。这些问题需要与用户的问题相关,并且引导进一步学习。 需要注意的是,用户提供的引用[2]可能和OkHttp无关,所以可能不需要引用,但需要检查是否有关联。根据用户的问题,引用[2]是关于Hadoop配置的,所以这里可以忽略。确保引用标识只在引用[1]出现的地方添加。 在回答过程中,要避免使用任何Markdown格式,除了代码块需要用反引号包裹,并且语言标识正确。同时,保持回答结构清晰,分步骤说明,确保用户能够逐步理解和应用OkHttp库。最后,生成的相关问题要简洁且有针对性,帮助用户深入探索相关主题。</think>### OkHttp库的使用与示例 OkHttp是一款高效的HTTP客户端库,支持SPDY协议、连接池、磁盘缓存和透明压缩,并通过Okio库实现对Java NIO的支持[^1]。以下是其核心用法和示例: --- #### **1. 添加依赖** 在项目的`build.gradle`中添加依赖: ```gradle implementation 'com.squareup.okhttp3:okhttp:4.9.3' // 以最新版本为准 ``` --- #### **2. 创建OkHttpClient实例** ```java OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) // 连接超时 .readTimeout(10, TimeUnit.SECONDS) // 读取超时 .build(); ``` --- #### **3. 发送同步GET请求** ```java 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(); } ``` --- #### **4. 发送异步GET请求** ```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); } } }); ``` --- #### **5. POST请求提交表单** ```java RequestBody formBody = new FormBody.Builder() .add("username", "test") .add("password", "123456") .build(); Request postRequest = new Request.Builder() .url("https://api.example.com/login") .post(formBody) .build(); // 发送请求(同步/异步) ``` --- #### **6. 配置拦截器** 拦截器可用于日志记录或修改请求: ```java OkHttpClient clientWithInterceptor = new OkHttpClient.Builder() .addInterceptor(chain -> { Request originalRequest = chain.request(); Request newRequest = originalRequest.newBuilder() .header("Authorization", "Bearer token") .build(); return chain.proceed(newRequest); }) .build(); ``` --- #### **7. 缓存配置** ```java File cacheDir = new File(context.getCacheDir(), "okhttp_cache"); int cacheSize = 10 * 1024 * 1024; // 10MB Cache cache = new Cache(cacheDir, cacheSize); OkHttpClient cachedClient = new OkHttpClient.Builder() .cache(cache) .build(); ``` --- ### **常见应用场景** - 移动应用与后端API通信 - 文件下载/上传 - 结合Retrofit实现RESTful请求(Retrofit默认使用OkHttp) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值