【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,一经查实,立即删除!

相关文章

使用v-model完成数据的双向绑定

创作灵感 面试问道了&#xff0c;没答出来&#xff0c;呜呜呜~ v-model实现双向绑定的原理 首先我们要知道&#xff0c;v-model实现的双向绑定其实只是props与emit的简化版本。其中&#xff0c;props负责父组件向子组件传递值&#xff0c;emit负责子组件向父组件传递值。 在…

视频推拉流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;是需要通过烧录器把编译好的镜像烧入到开发板里面的。这是很…

Spark RDD 操作实战

Spark RDD 基础 更多spark相关知识请查看官方接口文档 PySpark是Spark的PythonAPI&#xff0c;允许Python调用Spark编程模型。 配置spark环境 !apt-get install openjdk-8-jdk-headless -qq > /dev/null !wget -q www-us.apache.org/dist/spark/spark-2.4.8/spark-2.4.8…

16、Go Gin 深入理解Gin中间件

中间件介绍 Gin框架允许开发者在处理请求的过程汇总&#xff0c;加入用户自己的钩子&#xff08;Hook&#xff09;函数 这个钩子函数就叫中间件&#xff0c;中间件适合处理一些公共的业务逻辑 比如登录认证&#xff0c;权限校验、数据分页、记录日志、耗时统计等 1、全局中…

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…

数据赋能(98)——概念:数据整理、数据整合、数据处理

此文为本人学习与提高能力的笔记。 数据整理、数据整合与数据处理这三个术语&#xff0c;尽管在不少情境下可能被看作是近义词或拥有类似的语义范畴&#xff0c;但为了确保术语使用的精准度和专业性&#xff0c;我们必须对其有更为深入的认知。这三个概念虽在某种程度上相互交…

【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…

php 亚马逊AWS-S3对象存储上传文件

最近做国外项目的时候&#xff0c;需要把文件上传到AWS-S3对象存储空间里&#xff0c;下面整理一下上传方法&#xff0c;和碰到的问题 代码 /*** 亚马逊oss Aws上传* composer require aws/aws-sdk-php* param $filePath* param $ossPath* return array* author wzb* data 202…

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…

如何理解栈的增长方向

1、概念 函数调用栈&#xff0c;简称栈。不管是函数的执行还是函数调用&#xff0c;栈都起着非常重要的作用 保存函数的局部变量向被调用函数传递参数返回函数的返回值保存函数的返回地址。返回地址是指从被调用函数返回后调用者应该继续执行的指令地址 该文章会帮你很好的了…

Flutter 中的 ClipPath 小部件:全面指南

Flutter 中的 ClipPath 小部件&#xff1a;全面指南 在Flutter中&#xff0c;ClipPath是一个强大的小部件&#xff0c;它允许你通过一个路径来裁剪其子组件。这意味着你可以将任何小部件裁剪成圆形、矩形、或者任何你能通过Path定义的形状。本文将提供一个全面的指南&#xff…

AWS数据库之MemoryDB for Redis

NoSQL&#xff08;非关系型数据库&#xff09;通常可以分为内存数据库、文档数据库、图数据库、时序数据库等等。 适用于 Redis 的 MemoryDB 是一项耐用的内存数据库服务&#xff0c;可提供超快性能。它专为采用微服务架构的现代应用程序而构建。 MemoryDB 与 Redis&#xff…