子线程中创建 handler导致okhttp请求失败,从 ScheduledExecutorService 挖的坑开始

news2024/11/26 12:20:12

子线程创建方法1:

                ScheduledExecutorService schedulePool = Executors.newScheduledThreadPool(2);
                schedulePool.schedule(new Runnable() {
                    @Override
                    public void run() {
                        dorequest();
                    }
                }, 2, TimeUnit.SECONDS);

子线程创建方法2:

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        dorequest();
                    }
                }).start();

dorequest 代码: 

   Log.e("aaaaa", "dorequest");

        Request request = new Request.Builder() .url("http://www.baidu.com").build();
        okhttp3.OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();

            
        // 导致请求停止的原因
        Handler h = new Handler();

        clientBuilder.build().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e("aaaaa", "onFailure");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.e("aaaaa", "onResponse");

            }
        });


创建方法1 的运行结果:

方法运行中断,没有结果 。中断直接连网络请求都没有发出

创建方法2的运行结果:

直接crash,没有触发Looper.prepare()


问题的原因是在子线程中直接 new 了 handler 。如果不带 handler 时则正常。

由此有两种解决方案:

 方案一:补全 looper

private void dorequest(){
        Log.e("aaaaa", "dorequest");

        Request request = new Request.Builder() .url("http://www.baidu.com").build();
        okhttp3.OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();

        // 在new之前触发 prepare
        Looper.prepare();
        Handler h = new Handler();

        clientBuilder.build().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e("aaaaa", "onFailure");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.e("aaaaa", "onResponse");

            }
        });

        // 在完成时要 loop
        Looper.loop();
    }

方案二:指定主线程中创建 handler

// 修改这一句即可
Handler h = new Handler(Looper.getMainLooper());


这次写这个不是因为 looper,而是因为 schedulePool 在没有处理 looper 时居然不报错,而是直接return了,正好碰到这个问题,发现 okhttp 没有实际请求,查半天才发现是这个漏处理了,所以记录一下。

ScheduledExecutorService

特别需要注意,一旦SES执行的逻辑中抛出异常,那么调度会自动停止,并且不会有任何提示信息。在其scheduleWithFixedDelay()和scheduleAtFixedRate()方法的JavaDoc中,都有这样的描述:

ScheduledExecutorService (Java Platform SE 8 )

If any execution of the task encounters an exception, subsequent executions are suppressed.

Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given delay between the termination of one execution and the commencement of the next. If any execution of the task encounters an exception, subsequent executions are suppressed. Otherwise, the task will only terminate via cancellation or termination of the executor.

同时,通过线程工厂ThreadFactory设置异常处理器UncaughtExceptionHandler是没有作用的,也就是说SES遇到异常时根本不会调用uncaughtException()方法。

具体错误捕获,请参见:

ScheduledExecutorService异常处理的正确姿势-CSDN博客

Java中的定时任务-ScheduledExecutorService的坑 | yilan 

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

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

相关文章

数据结构—红黑树

红黑树介绍 红黑树(Red Black Tree)是一种自平衡二叉查找树。由于其自平衡的特性,保证了最坏情形下在 O(logn) 时间复杂度内完成查找、增加、删除等操作,性能表现稳定。 在 JDK 中,TreeMap、TreeSet 以及 JDK1.8 的 …

Leetcode算法训练日记 | day21

一、二叉搜索树的最小绝对差 1.题目 Leetcode:第 530 题 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数,其数值等于两值之差的绝对值。 示例 1: 输入:root [4,2,…

LeetCode 热题 100 题解(二):双指针部分(1)

题目一:移动零(No. 283) 题目链接:https://leetcode.cn/problems/move-zeroes/description/?envTypestudy-plan-v2&envIdtop-100-liked 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同…

(小红书平台)2024用户画像洞察报告

现今的小红书坐拥3亿月活用户,男女比例达到3:7,95后占比为50%,00后占比为35%,一二线城市用户占比50%。社区分享者超8000万,日均用户搜索渗透达到60%,UGC内容占比达90%。(数据来源:小…

C语言_文件操作

文件基础 什么是文件 文件是在计算机中以实现某种功能、或某个软件的部分功能为目的而定义的一个单位。磁盘上的文件是文件。但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件(从文件功能的角度来分的)。 程序文件 …

一分钟了解机器人自由度

目录 自由度的定义 自由度的分类 自由度的影响 影响自由度的主要参数 关节类型和数量 机械结构 控制系统 自由度控制的硬件架构原理 传感器 执行器 控制器 通信接口 软件和算法 机器人的自由度是指机器人在空间中可以独立移动的方向和角度的数量,它是衡…

STL容器之unordered_set类

文章目录 STL容器之unordered_set类1、unordered系列关联式容器2、unordered_set2.1、unordered_set介绍2.2、unordered_set的使用2.2.1、unordered_set的常见构造2.2.2、unordered_set的迭代器2.2.3、unordered_set的容量2.2.4、unordered_set的增删查2.2.5、unordered_set的桶…

看看《MATLAB科研绘图与学术图表绘制从入门到精通》示例:绘制山鸢尾萼片长度和萼片宽度的小提琴图

使用MATLAB绘制鸢尾花数据集( fisheriris)中山鸢尾( Iris Setosa)的萼片长度和 萼片宽度的小提琴图。这将帮助我们更好地了解山鸢尾的这两个特征的数据分布情况,包括它们的 中位数、四分位范围及密度估计。这种可视化工…

制造业、能源等传统行业进行数字化转型时要注意哪些问题?

制造业、能源等传统行业在进行数字化转型时需要注意以下几个关键问题: 1、明确转型目标和战略规划:企业需要根据自身的业务特点、市场需求和长远发展目标,制定清晰的数字化转型战略。包括确定转型的重点领域、预期成果、时间表和资源投入。 …

AI大模型探索之路-应用篇4:Langchain框架Memory模块—增强模型记忆与知识保留

目录 前言 一、概述 二、Conversation Buffer 三、Conversation Buffer Window 四、Conversation Summary 五、Conversation Summary Buffer 总结 前言 大模型技术在理解和生成自然语言方面表现出了惊人的能力。因此,为了实现长期的记忆保持和知识累积&#x…

【Java EE】获取Cookie和Session

文章目录 🎍Cookie简介🍀理解Session🌳Cookie 和 Session 的区别🌲获取Cookie🌸传统获取Cookie🌸简洁获取Cookie 🌴获取Session🌸Session存储🌸Session读取🌻…

内网IP与外网IP关联关系连接过程

前言 我们每天都会访问各种各样的网站,比如淘宝,百度等等。不免会思考,我们的设备是如何连接上这些网址的呢?要想搞清楚这个问题,首先就得先搞清楚内网ip和外网ip的联系。 网络结构 如图,假设我们的计算机…

IP协议中的四大支柱:DHCP、NAT、ICMP和IGMP的功能剖析

DHCP动态获取 IP 地址 我们的电脑通常都是通过 DHCP 动态获取 IP 地址,大大省去了配 IP 信息繁琐的过程。 客户端首先发起 DHCP 发现报文(DHCP DISCOVER) 的 IP 数据报,由于客户端没有 IP 地址,也不知道 DHCP 服务器的…

短剧在线搜索PHP网站源码

源码简介 短剧在线搜索PHP网站源码,自带本地数据库500数据,共有6000短剧视频,与短剧猫一样。 搭建环境 PHP 7.3 Mysql 5.6 安装教程 1.上传源码到网站目录中 2.修改【admin.php】中, $username ‘后台登录账号’; $passwor…

Android 14.0 SystemUI修改状态栏电池图标样式为横屏显示

1.概述 在14.0的系统rom产品定制化开发中,对于原生系统中SystemUId 状态栏的电池图标是竖着显示的,一般手机的电池图标都是横屏显示的 可以觉得样式挺不错的,所以由于产品开发要求电池图标横着显示和手机的样式一样,所以就得重新更换SystemUI状态栏的电池样式了 如图: 2.S…

通信分类3G,4G,5G,通信专用名词

Generation: 2G: GSM全名为:Global System for Mobile Communications,中文为全球移动通信系统,俗称"全球通",是一种起源于欧洲的移动通信技术标准,是第二代移动通信技术 3G:WCDMA 4G&#xff1a…

PaddleVideo:onnx模型导出

本文节介绍 PP-TSM 模型如何转化为 ONNX 模型,并基于 ONNX 引擎预测。 1:环境准备 安装 Paddle2ONNX python -m pip install paddle2onnx 安装 ONNXRuntime # 建议安装 1.9.0 版本,可根据环境更换版本号 python -m pip install onnxrunti…

flask 访问404

当你的项目有自己的蓝图,有添加自己的前缀,也注册了蓝图。 在访问的路由那里也使用了自己的蓝图,如下图 然后你访问的地址也没问题,但是不管怎么样访问就是返回404,这个时候不要怀疑你上面的哪里配置错误,…

彩虹聚合DNS管理系统源码

聚合DNS管理系统可以实现在一个网站内管理多个平台的域名解析,目前已支持的域名平台有:阿里云、腾讯云、华为云、西部数码、CloudFlare。本系统支持多用户,每个用户可分配不同的域名解析权限;支持API接口,支持获取域名…

标注平台工作流:如何提高训练数据质量与管理效率

世界发展日益依托数据的驱动,企业发现,管理不断增长的数据集却愈发困难。数据标注是诸多行业的一个关键过程,其中包括机器学习、计算机视觉和自然语言处理。对于大型语言模型(LLM)来说尤是如此,大型语言模型…