【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格式组装,发出请求的时候用get请求发出
#为了okhttp支持GET RequestBody-keepclassmembers public class okhttp3.Request {*** method;}/*** 让okhttp get请求支持body*/
public class FixGetWithBody {public static final String HEADER_KEY = "real_method";public static final String HEADER_VALUE = "GET";public static final String HEADER = HEADER_KEY + ": " + HEADER_VALUE;static ThreadLocal<Request> sThreadLocal = new ThreadLocal<>();
// TODO 第一步,在请求的时候,使用POST方式构造request,并且header里增加 HEADER_KEY,HEADER_VALUE,用来表示实际走GET请求/*** 添加到okhttp里** @return*/public static Interceptor getInterceptor() {return new InterceptorImpl();}/*** 添加到okhttp里*/public static EventListener getEventListener() {return new EventListenerImpl();}private static boolean needConvertToGet(Request request) {if (request == null) {return false;}return HEADER_VALUE.equalsIgnoreCase(request.header(HEADER_KEY));}private static void changeMethod(String method) {Request request = sThreadLocal.get();if (request != null) {try {Field field = Request.class.getDeclaredField("method");field.setAccessible(true);field.set(request, method);} catch (IllegalAccessException | NoSuchFieldException e) {}}}private static class EventListenerImpl extends EventListener {@Overridepublic void requestHeadersStart(Call call) {super.requestHeadersStart(call);// 在发送header之前,改回GET,这一步为了让服务端收到GET请求changeMethod("GET");}@Overridepublic void requestHeadersEnd(Call call, Request req) {super.requestHeadersEnd(call, req);// 为了让okhttp发送body,需要改为post,跳过get校验(因为post请求OKHTTP底层才发送body)// 不过此时header已经发送完成,改回POST也无妨。changeMethod("POST");sThreadLocal.remove();}}private static class InterceptorImpl implements Interceptor {@Overridepublic Response intercept(Chain chain) throws IOException {RealInterceptorChain realChain = (RealInterceptorChain) chain;Request request = realChain.request();if (needConvertToGet(request)) {request = request.newBuilder().removeHeader(HEADER_KEY).build();sThreadLocal.set(request);}return chain.proceed(request);}}
}

urlencode编码二次的问题The valid characters are defined in RFC 7230 and RFC 3986

问题描述
客户端发出的请求,服务端解析异常

问题分析

1.是TOMCAT报的错
2.和请求参数有关

问题解决
方法一:将json数据进行urlencode编码;
方法二:降低tomcat版本;
方法三:配置tomcat/conf下的catalina.properties

@Query注解默认将实体进行urlencode编码
使用@Query注解时,配置参数
如@Query(value=“”,encoded=true)
- encoded = true表示已经编码,无需让retrofit编码
encoded = false表示未编码,retrofit按情况编码

header不支持中文

问题描述

与后台协商协议,需要传递header参数,header的key-value存在中文,传递给后台,后台解析失败

问题分析

okhttp3 中 header 是不支持中文的

问题解决
URLEncoder编码传递中文,让后台用URLEncoder解码

java.lang.IllegalArgumentException: Could not locate call adapter for io.reactivex.Observable异常分析及解决

问题描述

新项目使用reftrofit与rxjava封装网络,报错Could not locate call adapter for io.reactivex.Observable

问题分析

rxjava版本不对,与retrofit不匹配

问题解决
选择合适的rxjava版本
在这里插入图片描述

回调都在子线程

问题描述
安卓不允许在子线程刷新ui;okhttp的callback回调仍然在子线程

问题分析

Call.enqueue(Callback cb),但是要注意 Callback 回调里面的方法全部是在子线程的。

问题解决

在主线程刷新ui,使用handler或者runOnUiThread

SocketTimeoutException或UnknownHostException

问题描述

请求http2.0,偶现UnknownHostException、SocketTimeoutException错误

问题分析
http1.1 支持 TCP 通道复用机制,http2.0 还支持了多路复用机制。
一般都是后台接口没有严格按照http1.1协议和http2.0协议来,导致服务器Socket关了,但是没有通知客户端,客户端下次请求,复用链路导致 SocketTimeoutException

问题解决

第一种:服务器端修改。

第二种:客户端关闭连接池 OkHttpClient.connectionPool().evictAll()。

第三种:客户端加重试机制,失败重新请求一次。推荐这种方式,失败重试可以解决很多其他网络偶然问题,比如快速切网的时候。

java.lang.SecurityException: Permission denied (missing INTERNET permission?)

问题描述

已经动态申请网络权限,还是报权限拒绝的错误,导致crash

问题分析

rom禁用了某个app的流量;rom禁止了app网络,看似给权限了,实际没给。

问题解决

识别到禁用后,捕获并提示用户,避免crash

// 添加 Interceptor 拦截器
public Response intercept(Chain chain) throws IOException {Request request = chain.request();Response response = null;try {response = chain.proceed(request);} catch (Throwable e) {throw new IOException(e);}return response;}

联系rom修改开放权限

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/14918.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频推拉流EasyDSS系统如何在清理缓存文件的同时不影响缓存读写?

视频推拉流EasyDSS视频直播点播平台可提供一站式的视频转码、点播、直播、视频推拉流、播放H.265视频等服务&#xff0c;搭配RTMP高清摄像头使用&#xff0c;可将无人机设备的实时流推送到平台上&#xff0c;实现无人机视频推流直播、巡检等应用。 有用户咨询&#xff0c;视频推…

Git 的安装和使用

一、Git 的下载和安装 目录 一、Git 的下载和安装 1. git 的下载 2. 安装 二、Git 的基本使用-操作本地仓库 1 初始化仓库 1&#xff09;创建一个空目录 2&#xff09;git init 2 把文件添加到版本库 1&#xff09;创建文件 2&#xff09;git add . 3&#xff09;g…

在SpringBoot自定义指标并集成Prometheus和Grafana监控

前沿 写这篇文章的目的是发现自己整天埋头写业务代码但忽略了主动发现问题的能力&#xff0c;这里指的是监控和报警。结合工作中发现Prometheus和Grafana还是主流一些。本文介绍如何使用自定义指标&#xff0c;并使用Prometheus进行监控并报警&#xff0c;同时在 Grafana 进行…

重学java 40.多线程 — 死锁和线程状态

—— 24.5. 一、死锁 1.死锁介绍&#xff08;锁嵌套就有可能产生死锁&#xff09; 指的是两个或者两个以上的线程在执行的过程中由于竞争同步锁而产生的一种阻塞现象;如果没有外力的作用,他们将无法继续执行下去,这种情况称之为死锁 例&#xff1a; 两线程处于互相等待的状态&a…

上位机图像处理和嵌入式模块部署(mcu常见三种烧录方法)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 和单纯的windows上位机开发、嵌入式linux开发不一样&#xff0c;mcu的开发&#xff0c;是需要通过烧录器把编译好的镜像烧入到开发板里面的。这是很…

STM32通用定时器的应用实例(基于STM32F103)

目录 概述 1 STM32Cube配置项目 1.1 准备环境 1.2 配置项目参数 1.3 生成Project 2 HAL函数 2.1 初始化函数&#xff1a;HAL_TIM_Base_Init 2.2 中断模式启动定时器函数&#xff1a;HAL_TIM_Base_Start 2.3 定时器回调函数&#xff1a; HAL_TIM_PeriodElapsedCallback…

ElasticSearch操作之重置密码脚本

ElasticSearch操作之重置密码脚本 #!/bin/bash # 使用样例 ./ES密码重置.sh 旧密码 新密码# 输入旧密码 es_old_password$1# 设置新的密码变量 es_password$2# 正确响应 es_reponse{"acknowledged":true}# 检查Elasticsearch是否在运行 if pgrep -f elasticsearch &g…

2024年5月计算机视觉论文推荐:包括扩散模型、视觉语言模型、图像编辑和生成、视频处理和生成以及图像识别等各个主题

我们今天总结下2024年5月发表的最重要的论文&#xff0c;重点介绍了计算机视觉领域的最新研究和进展&#xff0c;包括扩散模型、视觉语言模型、图像编辑和生成、视频处理和生成以及图像识别等各个主题。 Diffusion Models 1、Dual3D: Efficient and Consistent Text-to-3D Ge…

【C++题解】1697. 请输出n~1之间所有的整数

问题:1697. 请输出n~1之间所有的整数 类型&#xff1a;循环 题目描述&#xff1a; 从键盘读入一个整数 n &#xff0c;请输出 n∼1 之间所有的整数&#xff0c;每行输出 1 个。 比如&#xff0c;假设读入 n5 &#xff0c;输出结果如下&#xff1a; 5 4 3 2 1 输入&#xff1…

Java进阶学习笔记4——Static应用知识:代码块

代码块&#xff1a; 代码块是类的五大成员之一&#xff08;成员变量、构造器、方法、代码块、内部类&#xff09;。 Java类生命周期&#xff1a;加载、验证、准备、初始化、卸载。 代码块分为两种&#xff1a; 静态代码块&#xff1a; 格式&#xff1a;static {} 特点&…

SpringBoot 集成 Nebula

工作需求&#xff0c;开始了解图数据库&#xff0c;经过工具选型&#xff0c;最终选择nebula graph&#xff0c;并集成到springboot&#xff0c;java 环境下如何对 Nebula Graph 进行操作&#xff0c;本文整理下过程。 1、首先引入 pom 依赖 <dependency><groupId&g…

鸿蒙系统与OpenHarmony:中国科技行业的新动力与就业前景

背景 经历近年来的迅猛发展&#xff0c;鸿蒙原生应用数量已突破4000款&#xff0c;生态设备数量超过8亿台&#xff0c;开发者群体壮大至220万人。更为显著的是&#xff0c;鸿蒙系统在中国市场的份额已经超过了15%&#xff0c;稳居第三大操作系统&#xff0c;其生态之树已然枝繁…

探秘机器学习经典:K-近邻算法(KNN)全解析

在浩瀚的机器学习宇宙中,K-近邻算法(K-Nearest Neighbors,简称KNN)如同一颗璀璨的明星,以其简洁直观的原理和广泛的应用范围,赢得了众多数据科学家的喜爱。今天,让我们一起揭开KNN的神秘面纱,深入探讨它的运作机制、优缺点、应用场景,以及如何在实际项目中灵活运用。 …

23. 【Java教程】接口

本小节我们将学习 Java 接口&#xff08;interface&#xff09;&#xff0c;通过本小节的学习&#xff0c;你将了解到什么是接口、为什么需要接口、如何定义和实现接口&#xff0c;以及接口的特点等内容。最后我们也将对比抽象类和接口的区别。 1. 概念 Java 接口是一系列方法的…

PostgreSQL事务基础理解

PostgreSQL事务 事务是数据库管理系统执行过程中的一个逻辑单位&#xff0c;由一个有限的数据库操作序列构成。数据库事务通常包含一个序列对数据库的读和写操作&#xff0c;主要是包含以下两个目的&#xff1a; 为数据库操作序列提供一个从失败中恢复到正常状态的方法&#…

事务管理控制

文章目录 1. 事务的基本概念2. 数据库的并发控制2.1 事务调度2.2 并发操作带来的问题2.3 并发调度的可串行性2.4 并发控制技术2.5 两段锁协议2.6 多粒度封锁协议 3. 数据库的备份与恢复3.1 数据库系统故障3.2 数据库的备份3.3 数据库的恢复 4. 数据库的安全性与完整性4.1 数据库…

VMware虚拟机桥接无线网卡上网(WIFI)

一、打开VM点击【编辑】-【虚拟网络编辑器】 二、点击【桥接模式】- 点击【自动设置】- 选择自己的无线网适配器 - 【确定】 三、开机之后会弹出提示连接网络&#xff0c;就能看见网络已经连上了

网络变压器原理与维修视频

如果你在寻找网络变压器原理与维修方面的视频教程&#xff0c;可以在网上找一些优质的资料进行学习。一些国内外知名的教育和科技资源网站&#xff0c;如B站、优酷、YouTube等&#xff0c;都有涉及网络变压器原理和维修的视频教程&#xff0c;你可以在这些网站上进行搜索。 通常…

智慧之选:开源与闭源大模型的未来探索

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

淘宝订单系统ERP中如何接入平台订单信息?(订单API)

淘宝开放平台中有交易API&#xff0c;里面有各种关于交易的API接口。但是申报应用权限的审核流程严格又漫长。不少公司费时费力的申请后&#xff0c;结果还是没有审批下来。 调用淘宝自定义接口custom&#xff0c;可以实现淘宝开放平台API的调用。技术人员会根据您需要的接口做…