关于@hide的理解
在上一篇文章《学习HandlerThread》我们提到虽然HandlerThread类里有getThreadHandler()方法得到Handler,但是我们不可能调用到它。因为这个方法用@hide
注释了
/*** @return a shared {@link Handler} associated with this thread* @hide*/@NonNullpublic Handler getThreadHandler() {if (mHandler == null) {mHandler = new Handler(getLooper());}return mHandler;}
那么我们来看看@hide
究竟是何方神圣。
如果我们的android项目的build.gradle配置了compileSdk 32
,那么在我们编译我们android应用时,$ANDROID_SDK_HOME/platforms/android-32/android.jar
就会加入我们编译时的类路径中,参与app的编译。@hide
会控制我们编译时用到的这个android.jar包里的东西。
android.jar作为编译android本身的一部分被创建。Android framework的类会被分析,并创建它们的副本。这个副本有以下特点:
- 去除被标注了
@hide
的类、方法、字段等 - 所有剩下的方法都有stub实现,即
throw new RuntimeException("Stub!")
- 保留所有没有被去除的类、方法、字段的JavaDoc注解
我们使用javap命令查看一下android.os.HandlerThread.class里的东西:
% javap -verbose android/os/HandlerThread.class
从下面我们可以看到HandlerThread.class确实没有了getThreadHandler方法。
Classfile
***/adddd/android/android/os/HandlerThread.classLast modified Jan 1, 2008; size 1043 bytesSHA-256 checksum 8161f60748df5cf7489dbf189c3f4668d81a17595dbd55e52baa0f8263bb96d4Compiled from "HandlerThread.java"
public class android.os.HandlerThread extends java.lang.Threadminor version: 0major version: 52flags: (0x0021) ACC_PUBLIC, ACC_SUPERthis_class: #5 // android/os/HandlerThreadsuper_class: #6 // java/lang/Threadinterfaces: 0, fields: 0, methods: 8, attributes: 1
Constant pool:#1 = Methodref #6.#31 // java/lang/Thread."<init>":()V#2 = Class #32 // java/lang/RuntimeException#3 = String #33 // Stub!#4 = Methodref #2.#34 // java/lang/RuntimeException."<init>":(Ljava/lang/String;)V#5 = Class #35 // android/os/HandlerThread#6 = Class #36 // java/lang/Thread#7 = Utf8 <init>#8 = Utf8 (Ljava/lang/String;)V#9 = Utf8 Code#10 = Utf8 LineNumberTable#11 = Utf8 LocalVariableTable#12 = Utf8 this#13 = Utf8 Landroid/os/HandlerThread;#14 = Utf8 name#15 = Utf8 Ljava/lang/String;#16 = Utf8 (Ljava/lang/String;I)V#17 = Utf8 priority#18 = Utf8 I#19 = Utf8 onLooperPrepared#20 = Utf8 ()V#21 = Utf8 run#22 = Utf8 getLooper#23 = Utf8 ()Landroid/os/Looper;#24 = Utf8 quit#25 = Utf8 ()Z#26 = Utf8 quitSafely#27 = Utf8 getThreadId#28 = Utf8 ()I#29 = Utf8 SourceFile#30 = Utf8 HandlerThread.java#31 = NameAndType #7:#20 // "<init>":()V#32 = Utf8 java/lang/RuntimeException#33 = Utf8 Stub!#34 = NameAndType #7:#8 // "<init>":(Ljava/lang/String;)V#35 = Utf8 android/os/HandlerThread#36 = Utf8 java/lang/Thread
{public android.os.HandlerThread(java.lang.String);descriptor: (Ljava/lang/String;)Vflags: (0x0001) ACC_PUBLICCode:stack=3, locals=2, args_size=20: aload_01: invokespecial #1 // Method java/lang/Thread."<init>":()V4: new #2 // class java/lang/RuntimeException7: dup8: ldc #3 // String Stub!10: invokespecial #4 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V13: athrowLineNumberTable:line 23: 0LocalVariableTable:Start Length Slot Name Signature0 14 0 this Landroid/os/HandlerThread;0 14 1 name Ljava/lang/String;public android.os.HandlerThread(java.lang.String, int);descriptor: (Ljava/lang/String;I)Vflags: (0x0001) ACC_PUBLICCode:stack=3, locals=3, args_size=30: aload_01: invokespecial #1 // Method java/lang/Thread."<init>":()V4: new #2 // class java/lang/RuntimeException7: dup8: ldc #3 // String Stub!10: invokespecial #4 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V13: athrowLineNumberTable:line 25: 0LocalVariableTable:Start Length Slot Name Signature0 14 0 this Landroid/os/HandlerThread;0 14 1 name Ljava/lang/String;0 14 2 priority Iprotected void onLooperPrepared();descriptor: ()Vflags: (0x0004) ACC_PROTECTEDCode:stack=3, locals=1, args_size=10: new #2 // class java/lang/RuntimeException3: dup4: ldc #3 // String Stub!6: invokespecial #4 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V9: athrowLineNumberTable:line 27: 0LocalVariableTable:Start Length Slot Name Signature0 10 0 this Landroid/os/HandlerThread;public void run();descriptor: ()Vflags: (0x0001) ACC_PUBLICCode:stack=3, locals=1, args_size=10: new #2 // class java/lang/RuntimeException3: dup4: ldc #3 // String Stub!6: invokespecial #4 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V9: athrowLineNumberTable:line 29: 0LocalVariableTable:Start Length Slot Name Signature0 10 0 this Landroid/os/HandlerThread;public android.os.Looper getLooper();descriptor: ()Landroid/os/Looper;flags: (0x0001) ACC_PUBLICCode:stack=3, locals=1, args_size=10: new #2 // class java/lang/RuntimeException3: dup4: ldc #3 // String Stub!6: invokespecial #4 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V9: athrowLineNumberTable:line 31: 0LocalVariableTable:Start Length Slot Name Signature0 10 0 this Landroid/os/HandlerThread;public boolean quit();descriptor: ()Zflags: (0x0001) ACC_PUBLICCode:stack=3, locals=1, args_size=10: new #2 // class java/lang/RuntimeException3: dup4: ldc #3 // String Stub!6: invokespecial #4 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V9: athrowLineNumberTable:line 33: 0LocalVariableTable:Start Length Slot Name Signature0 10 0 this Landroid/os/HandlerThread;public boolean quitSafely();descriptor: ()Zflags: (0x0001) ACC_PUBLICCode:stack=3, locals=1, args_size=10: new #2 // class java/lang/RuntimeException3: dup4: ldc #3 // String Stub!6: invokespecial #4 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V9: athrowLineNumberTable:line 35: 0LocalVariableTable:Start Length Slot Name Signature0 10 0 this Landroid/os/HandlerThread;public int getThreadId();descriptor: ()Iflags: (0x0001) ACC_PUBLICCode:stack=3, locals=1, args_size=10: new #2 // class java/lang/RuntimeException3: dup4: ldc #3 // String Stub!6: invokespecial #4 // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V9: athrowLineNumberTable:line 37: 0LocalVariableTable:Start Length Slot Name Signature0 10 0 this Landroid/os/HandlerThread;
}
SourceFile: "HandlerThread.java"
这里再介绍一下从这个HandlerThread.class里面看到的一些信息:
- minor version: 0 major version: 52:表示当前这个.class文件是用哪个编译器生产的
JDK Version | (in Decimal) Major Version |
---|---|
Java SE 8.0 | 52 |
Java SE 11.0 | 55 |
- Compiled from “HandlerThread.java”:说明.class文件是由这"HandlerThread.java"编译而来的
相关文章:

关于@hide的理解
在上一篇文章《学习HandlerThread》我们提到虽然HandlerThread类里有getThreadHandler()方法得到Handler,但是我们不可能调用到它。因为这个方法用hide注释了 /*** return a shared {link Handler} associated with this thread* hide*/NonNullpublic Handler getT…...

使用python加密主机文件几种方法实现
本文主要介绍了使用python加密主机文件几种方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧数据加密是一种保护数据安全的技术,通过对数据进行编…...

西湖论剑 2023 比赛复现
WEB real_ez_node 在 route/index.js 中: router.post(/copy,(req,res)>{res.setHeader(Content-type,text/html;charsetutf-8)var ip req.connection.remoteAddress;console.log(ip);var obj {msg: ,}if (!ip.includes(127.0.0.1)) {obj.msg"only for…...
微信小程序更换管理员/重置管理员
方式1: 首先进入微信公众平台官网进入并登录后在管理中找到成员管理选项找到管理员点击后方的修改选项需要使用原管理员的微信进行扫码验证扫码后在手机上确认绑定新管理员,注意:如果是个人账号不可以更改成其他人。 方式2:原管…...

企业进存销管理系统
技术:Java、JSP等摘要:随着当今世界计算机技术的飞速发展,计算机在企业管理中应用的普及,利用计算机实现企业进销存管理势在必行。本系统结合公司实际的进销存制度,通过对本公司的供应商、客户、商品、进货、销售、进销…...

C++入门
变量变量创建的语法: 数据类型 变量名 变量初始值;int a 10;cout << a << endl;常量作用:用于记录程序中不可更改的教国C定义常量两种方式1).#define 宏常量:#define 常量名 常量值通常在文件上方定义。表示一个常量2).const 修饰的变量const 数据类型 常量名 常…...
视频知识点(20)- H264码流如何在SPS中获取宽高信息?
《音视频开发》系列-总览 前沿 了解H264视频编码格式的小伙伴都知道,H264编码中存在两个非常重要的参数集。没错,它们就是序列参数集(SPS)和图像参数集(PPS),而且通常情况下,PPS会依赖SPS中的部分参数信息,同时,视频码流的宽高信息也存储在SPS中。那么如何从中获取视…...

鲜花数据集实验结果总结
从read_split_data中得到:训练数据集,验证数据集,训练标签,验证标签。的所有的具体详细路径 数据集位置:https://download.csdn.net/download/guoguozgw/87437634 import os #一种轻量级的数据交换格式, …...

ElasticJob-Lite架构篇 - 认知分布式任务调度ElasticJob-Lite
前言 本文基于 ElasticJob-Lite 3.x 版本展开分析。 如果 Quartz 集群中有多个服务端节点,任务决定在哪个服务端节点上执行的呢? Quartz 采用随机负载,通过 DB 抢占下一个即将触发的 Trigger 绑定的任务的执行权限。 在 Quartz 的基础上&…...
【直击招聘C++】2.6 对象之间的复制
2.6 对象之间的复制一、要点归纳1. 对象之间的复制操作1.1 运算符1.2 拷贝构造函数2. 对象之间的浅复制和深复制2.1 对象的浅复制2.2 对象的深复制二、面试真题解析面试题1面试题2一、要点归纳 1. 对象之间的复制操作 同一个类的对象之间可以进行复制操作,即将一个…...

学了这么久python,不会连自己啥python版本都不知道吧?
人生苦短,我用Python 源码资料电子书:点击此处跳转文末名片获取 查看 Python 版本 我们可以在命令窗口(Windows 使用 winR 调出 cmd 运行框)使用以下命令查看我们使用的 Python 版本: python -V 或 python --version 以上命令执行结果如下: …...

Revive:从间谍软件进化成银行木马
2022 年 6 月,Cleafy 研究人员发现了一个新的安卓银行木马 Revive。之所以选择 Revive 这个名称,是因为恶意软件为防止停止工作启用的一项功能名为 revive。 Revive 属于持续潜伏的那一类恶意软件,因为它是为特定目标开发和定制的。这种类型…...

Python 之 NumPy 简介和创建数组
文章目录一、NumPy 简介1. 为什么要使用 NumPy2. NumPy 数据类型3. NumPy 数组属性4. NumPy 的 ndarray 对象二、numpy.array() 创建数组1. 基础理论2. 基础操作演示3. numpy.array() 参数详解三、numpy.arange() 生成区间数组四、numpy.linspace() 创建等差数列五、numpy.logs…...

与六年测试工程师促膝长谈,他分享的这些让我对软件测试工作有了全新的认知~
不知不觉已经从事软件测试六年了,2016年毕业到进入外包公司外包给微软做软件测试, 到现在加入著名的外企。六年的时间过得真快。长期的测试工作也让我对软件测试有了比较深入的认识。但是我至今还是一个底层的测试人员,我的看法都比较狭隘&am…...
裕太微在科创板上市:市值约186亿元,哈勃科技和小米基金为股东
2月10日,裕太微电子股份有限公司(下称“裕太微”,SH:688515)在上海证券交易所上市。本次上市,裕太微的发行价为92元/股,发行2000万股,发行市盈率不适用,发行后总股本8000万股。 根据…...

毕业后5年,我终于变成了月薪13000的软件测试工程师
我用了近2个月的时间转行,在今年1月底顺利入职了一家北京的互联网公司,从事的是软件测试的工作。 和大家看到的一样,我求职的时间花费的比较短,求职过程非常顺利,面试了一周就拿到了3家offer,3家offer的薪…...

实践指南|如何在 Jina 中使用 OpenTelemetry 进行应用程序的监控和跟踪
随着软件和云技术的普及,越来越多的企业开始采用微服务架构、容器化、多云部署和持续部署模式,这增加了因系统失败而给运维/ SRE / DevOps 团队带来的压力,从而增加了开发团队和他们之间的摩擦,因为开发团队总是想尽快部署新功能&…...

MySQL 创建数据表
在创建数据库之后,接下来就要在数据库中创建数据表。所谓创建数据表,指的是在已经创建的数据库中建立新表。 创建数据表的过程是规定数据列的属性的过程,同时也是实施数据完整性(包括实体完整性、引用完整性和域完整性)…...
一文详解网络安全事件的防护与响应
网络安全事件的发生,往往意味着一家企业的生产经营活动受到影响,甚至数据资产遭到泄露。日益复杂的威胁形势使现代企业面临更大的网络安全风险。因此,企业必须提前准备好响应网络安全事件的措施,并制定流程清晰、目标明确的事件响…...

vue directive 注册局部指令
注册局部指令 vue directive 在注册局部指令时,是通过在组件 options 选项中设置 directives 属性。如下: directives: {focus: {// 指令的定义inserted: function (el) {el.focus()}} }在模板中的任何元素上都可以使用新的 v-focus propertyÿ…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...

莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...

tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...
深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向
在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)
错误一:yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因,后面把yaml.safe_dump直接替换成yaml.dump,确实能保存,但出现乱码: 放弃yaml.dump,又切…...