Android 性能优化之黑科技开道(一)
1. 缘起
在开发电视版智家 App9.0 项目的时候,发现了一个性能问题。电视系统原本剩余的可用资源就少,而随着 9.0 功能的进一步增多,特别是门铃、门锁、多路视频同屏监控后等功能的增加,开始出现了卡顿情况。
经过调研分析发现有一部分是日志输出导致的,profiler 工具显示有一个日志输出的线程会有频繁占用 CPU 时间片的现象。
2. 性能优化引起的 Android 日志开关控制问题及解决
2.1 查看日志线程的 CPU 占用率
使用 Profiler 查看 CPU 占用率,在打开日志及关闭日志的情况下分别如下:
(图 1 日志开关打开的情况)
(图 2 日志开关关闭的情况下)
由上可以看出,存在两个问题:
-
日志开关打开的情况下,占用 CPU 时间比较多
-
日志开关关闭的情况下,比打开的情况好一些,但还是会有一些 CPU 占用,通过打日志发现,是有一些日志没有关闭,还在频繁的继续打印
2.2 需要日志开关方案?
-
发现关不掉的 TAG 大部分第三方库中的,它们没有对外提供使能接口,导致日志关不掉,为了性能考虑,需要对第三方库中的日志进行控制,在必要时可以关闭它们;
-
如果线上的版本不关闭日志,会存在用户隐私或产品信息泄漏的风险,为了 APP 和用户安全考虑,需要关闭线上版本的日志输出;
-
另外,为了更加方便的发现错误,我们应该对日志级别进行控制,例如我们可以采用如下方案:无论任何时候都输出 E 级别日志,其它级别日志可以根据情况进行关闭;
结论:我们需要一个统一关闭和控制所有日志的开关方案。
2.3 方案调研
方案 | 方案介绍 | 优点 | 缺点 |
混淆 | 采用混淆 proguard 配置方式关闭 APP 日志输出,包括: android.util.Log 类 java.io.PrintStream 类(java.lang.System.out.println( )和 java.lang.System.out.print()系列) | 实现简单,想关哪个关哪个 |
|
插桩+ASM | 通过 AOP 编程,在日志输出的某个类中进行字节码插桩,实现控制日志输出的目的 | 灵活,稳定性高 |
|
Hook | 通过反射或其它技术,针对日志输出的某一个实现点,进行 Hook,进而实现控制的目的 | 灵活,稳定性高 |
|
混淆
-
混淆方案有个缺点,就是不能通过开关动态的调节日志开关,先做为备选吧
插桩
-
经过技术预研,发现插桩的方案如果选用 Transform, 只能修改自己写的类或者是第三方库中的类,而影响不到 Android SDK 中的类 android.util.Log
-
在暂时未找到其它插桩点的情况下,此方案行不通
Hook
-
Hook 方案有很多种,需要根据具体的情况进行分析,选择合适的方案
Hook 技术 | 适用范围 | 主要原理 | 优点 | 缺点 |
反射+动态代理 | Java 层部分场景 | 虚拟机提供的能力 | 稳定性高 技术门槛低 | 适用范围小 |
ClassLoader 修改 | Java 层全部 | 修改 ClassLoader 加载类的顺序 | 稳定性高,Java 层都可以替换 | 需要提前准备好替换的 Dex |
JNI Hook | Java 层与 native 间的函数 | native 函数指针存储在表中,重定向表中的函数指针 | 稳定性高 | 只能 Hook native 方法 |
Xposed 类 | Java 层全部 | 虚拟机中的目标函数为 Native,然后利用 JNI hook 重定向 | java 层全 hook,hook 接口友好,有大量 Hook 插件可以使用和参考 | ART/Dalvik 虚拟机每个版本都有不少改动,需适配。稳定性较差 |
GOT | native 层动态链接库入口函数 | Linux 进程会链接 so 到内存中,并给 so 的入口函数们分配地址。原理是重定向入口地址 | 稳定性高 | 只能 Hook so 的入口函数,不能 Hook so 的内部 |
Inline hook | native 层全部 | 目标函数执行指令代码中插入 Jump 指令实现重定向 | hook native everything | 和 cpu 指令集相关,需要针对性汇编实现,稳定性较一般,技术门槛相对高 |
-
经过分析,发现
-
Java 层的两种方案(反射+动态代理、ClassLoader 修改)不能满足我们的需求
-
Native 的两种方案(GOT 和 inline hook)确实很强大,但在这里我们还用不到修改这么底层的内容
-
而 Xposed 框架类型的方案又太重
-
对比后发现,JniHook 正好能够满足我们的需求。Hook 并重定向 android.util.Log 类中的 native 方法(print_native)即可满足要求。
-
2.4 实现原理(对 Log 类进行 JniHook)
原理图:
2.5 最终效果
1. 通过我们的开关控制逻辑关闭了所有的 Java 日志,并保留 Error 级别的日志输出,如下图
2. 收益
-
提升了性能,CPU 占用率减少约 17%
-
有效防止了敏感信息泄漏,保护了用户隐私
-
使用自己的策略灵活管控了日志的输出
其它可以黑科技优化的方向是什么?下期敬请期待~
3. 团队介绍
「三翼鸟数字化技术平台-场景设计交互平台」主要负责设计工具的研发,包括营销设计工具、家电VR设计和展示、水电暖通前置设计能力,研发并沉淀素材库,构建家居家装素材库,集成户型库、全品类产品库、设计方案库、生产工艺模型,打造基于户型和风格的AI设计能力,快速生成算量和报价;同时研发了门店设计师中心和项目中心,包括设计师管理能力和项目经理管理能力。实现了场景全生命周期管理,同时为水,空气,厨房等产业提供商机管理工具,从而实现了以场景贯穿的B端C端全流程系统。
相关文章:
Android 性能优化之黑科技开道(一)
1. 缘起 在开发电视版智家 App9.0 项目的时候,发现了一个性能问题。电视系统原本剩余的可用资源就少,而随着 9.0 功能的进一步增多,特别是门铃、门锁、多路视频同屏监控后等功能的增加,开始出现了卡顿情况。 经过调研分析发现有…...
Successive Convex Approximation算法的学习笔记
文章目录 一、代码debug二、原理 本文主要参考了CSDN上的 另一篇文章,但规范了公式的推导过程和修缮了部分代码 一、代码debug 首先,我们将所有的代码放到MATLAB中,很快在命令行中出现了错误信息 很显然有问题,但是我不知道发生…...
IoT数采平台2:文档
IoT数采平台1:开篇IoT数采平台2:文档IoT数采平台3:功能IoT数采平台4:测试 【平台功能】 基础配置、 实时监控、 规则引擎、 告警列表、 系统配置 消息通知:Websocket 设备上线、设备下线、 数据变化、 告警信息、 实时…...
Vue监听器watch的基本用法
文章目录 1. 作用2. 格式3. 示例3.1 value 值为字符串3.2 value 值为函数3.3 value 值为对象 4. 与计算属性对比 1. 作用 监视数据变化,执行一些业务逻辑或异步操作。 2. 格式 监听器 watch 内部以 key :value 的形式定义,key 是 data 中的…...
MySQL UPDATE JOIN 根据一张表或多表来更新另一张表的数据
当使用MySQL时,经常需要根据一张表或多张表的数据来更新另一张表的数据。这种情况下,我们可以使用UPDATE语句结合JOIN操作来实现这一需求。本文将介绍MySQL中使用UPDATE JOIN的技术。 什么是UPDATE JOIN UPDATE JOIN是MySQL中一种结合UPDATE语句和JOIN…...
JS实现继承的方式ES6版
上一篇:JS实现继承的方式原生版 ES6的继承 主要是依赖extends关键字来实现继承,且继承的效果类似于寄生组合继承。 class Parent() { }class Child extends Parent {constructor(x, y, color) {super(x, y);this.color color;} }子类必须在construct…...
elementui 左侧或水平导航菜单栏与main区域联动
系列文章目录 一、elementui 导航菜单栏和Breadcrumb 面包屑关联 二、elementui 左侧导航菜单栏与main区域联动 三、elementui 中设置图片的高度并支持PC和手机自适应 四、elementui 实现一个固定位置的Pagination(分页)组件 文章目录 系列文章目录…...
YUNBEE云贝-技术分享:PostgreSQL分区表
引言 PostgreSQL作为一款高度可扩展的企业级关系型数据库管理系统,其内置的分区表功能在处理大规模数据场景中扮演着重要角色。本文将深入探讨PostgreSQL分区表的实现逻辑、详细实验过程,并辅以分区表相关的视图查询、分区表维护及优化案例,…...
5.2 通用代码,数组求和,拷贝数组,si配合di翻转数组
5.2 通用代码,数组求和,拷贝数组,si配合di翻转数组 1. 通用代码 通用代码类似于一个用汇编语言写程序的一个框架,也类似于c语言的头文件编写 assume cs:code,ds:data,ss:stack data segmentdata endsstack segmentstack endsco…...
Oracle23免费版简易安装攻略
installation-guide 1 安装 root用户下 wget https://yum.oracle.com/repo/OracleLinux/OL8/developer/x86_64/getPackage/oracle-database-preinstall-23c-1.0-1.el8.x86_64.rpm wget https://download.oracle.com/otn-pub/otn_software/db-free/oracle-database-free-23c-1…...
《论文阅读》一种基于反事实推理的会话情绪检测无训练去偏框架 EMNLP 2023
《论文阅读》一种基于反事实推理的会话情绪检测无训练去偏框架 EMNLP 2023 前言简介相关工作模型构架Basic ClassificationBias ExtractionUnbiased Inference实验结果前言 亲身阅读感受分享,细节画图解释,再也不用担心看不懂论文啦~ 无抄袭,无复制,纯手工敲击键盘~ 今天…...
【编译lombok问题】已解决:编译突然找不到符号问题-get/set找不到符号
一、场景:编译突然找不到符号 报错信息: 找不到符号 符号:方法getName() 二、原因: 没有使用lombok支持的编译器 三、解决方法: 打开File-Settings,按以下步骤进行设置; 修改:-Djp…...
第四篇:3.3 无效流量(Invalid traffic) - IAB/MRC及《增强现实广告效果测量指南1.0》
翻译计划 第一篇概述—IAB与MRC及《增强现实广告效果测量指南》之目录、适用范围及术语第二篇广告效果测量定义和其他矩阵之- 3.1 广告印象(AD Impression)第三篇广告效果测量定义和其他矩阵之- 3.2 可见性 (Viewability)第四篇广…...
PyTorch示例——使用Transformer写古诗
文章目录 PyTorch示例——使用Transformer写古诗1. 前言2. 版本信息3. 导包4. 数据与预处理数据下载先看一下原始数据开始处理数据,过滤掉异常数据定义 词典编码器 Tokenizer定义数据集类 MyDataset测试一下MyDataset、Tokenizer、DataLoader 5. 构建模型位置编码器…...
vue 视频添加水印
1.需求背景 其实腾讯云点播的api也支持视频水印,但是只有单个水印,大概效果是这样子的,不满足我们的需求,我们的需求是需要视频中都是水印。 腾讯云点播水印 项目需求的水印(主要是防录屏,最后的实现效果是这样&…...
Web Animations API 动画
Element.animate() dom.animate动画可以避免污染dom原有的css动画 参考资料 Element.animate() - Web API 接口参考 | MDN Element: getAnimations() method - Web APIs | MDN .tunnel{width:200px;height:200px;background-color:#38f;}<div class"tunnel" …...
【大数据存储】实验五:Mapreduce
实验Mapreduce实例——排序(补充程序) 实验环境 Linux Ubuntu 16.04 jdk-8u191-linux-x64 hadoop-3.0.0 hadoop-eclipse-plugin-2.7.3.jar eclipse-java-juno-SR2-linux-gtk-x86_64 实验内容 在电商网站上,当我们进入某电商页面里浏览…...
日志服务 HarmonyOS NEXT 日志采集最佳实践
作者:高玉龙(元泊) 背景信息 随着数字化新时代的全面展开以及 5G 与物联网(IoT)技术的迅速普及,操作系统正面临前所未有的变革需求。在这个背景下,华为公司自主研发的鸿蒙操作系统(…...
Educational Codeforces Round 133 (Rated for Div. 2) (C dp D前缀和优化倍数关系dp)
A:能用3肯定用三,然后分类讨论即可 #include<bits/stdc.h> using namespace std; const int N 2e510,M2*N,mod998244353; #define int long long typedef long long LL; typedef pair<int, int> PII; typedef unsigned long long ULL; usi…...
【讲解下如何Stable Diffusion本地部署】
🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…...
wps斜线表头并分别打字教程
wps斜线表头怎么做并分别打字: 1、首先选中我们想要设置的表头。 2、接着右键选中它,点击“设置单元格格式” 3、然后点击上方“边框”选项卡。 4、随后选择图示的斜线,点击“确定” 5、设置完成后,我们只要在其中打字就可以在斜…...
2024第八届全国青少年无人机大赛暨中国航空航天科普展览会
2024第八届全国青少年无人机大赛暨中国航空航天科普展览会 邀请函 主办单位: 中国航空学会 重庆市南岸区人民政府 招商执行单位: 重庆港华展览有限公司 为更好的培养空航天产业人才,汇聚航空教育产业创新科技,丰富和完善航…...
fastadmin学习08-查询数据渲染到前端
index.php查询,这个是前台的index.php public function index() {$slideImgs Db::name("slideimg")->where("status",,normal)->limit(5)->order(sort,desc)->select();$productList Db::name("product")->where(…...
实验报告答案
基本任务(必做) 先用普通用户(自己的姓名拼音)登录再操作 编程有代码截图和执行过程结果截图 代写获取: https://laowangall.oss-cn-beijing.aliyuncs.com/studentall.pdf 1. Linux的Shell编程 (1&am…...
PDF编辑和格式转换工具 Cisdem PDFMaster for Mac
Cisdem PDFMaster for Mac是一款功能强大的PDF编辑和格式转换工具。它为用户提供了直观且易于使用的界面,使常用功能触手可及,从而帮助用户轻松管理、编辑和转换PDF文件。 软件下载:Cisdem PDFMaster for Mac v6.0.0激活版下载 作为一款完整的…...
E-魔法猫咪(遇到过的题,做个笔记)
题解: 来自学长们思路: 其中一种正解是写单调队列。限制队列内的数单调递增,方法为每当新来的数据比当前队尾数据小时队 尾出列,直到能够插入当前值,这保证了队头永远是最小值。因此总体思路是队尾不断插入新值的同时 …...
keil创建工程 芯源半导体CW32F003E4P7
提前下载keil 安装步骤 1、下载CW32F003固件库 芯源半导体官网下载固件库 下载好后右键解压 CW32F003_StandardPeripheralLib_V1.5\IdeSupport\MDK 进入MDK文件夹 双击WHXY.CW32F003_DFP.1.0.4.pack安装固件库 点击next然后finish安装结束 keil创建工程 点击new uVision P…...
学习鸿蒙基础(12)
目录 一、网络json-server配置 (1)然后输入: (2)显示下载成功。但是输入json-server -v的时候。报错。 (3)此时卸载默认的json-server (4)安装和nodejs匹配版本的js…...
HTML5和CSS3笔记
一:网页结构(html): 1.1:页面结构: 1.2:标签类型: 1.2.1:块标签: 1.2.2:行内标签: 1.2.3:行内块标签: 1.2.4:块标签与行…...
营销型网站建设文章/ 今日头条
atitit 点播系统 概览 v2 qb1.docx 1.1. 多界面(可以挂载多个不同的界面主题)1 1.2. 独立的选片模块(跨设备,跨平台)2 1.3. 跨设备平台(android安卓盒子,pc,htpc )2 1.4…...
wordpress虚拟主机vps/seo综合查询中的具体内容有哪些
本篇讲解Ext另一个重要的概念:布局。一般的容器类控件都是通过配置项items添加子控件的,这些子控件相对于父控件怎么定位呢,这里就要用到布局。某些容器类控件,它本身默认就集成了一种布局方式,例如比较典型的是&#…...
网站日志文件夹/茶叶网络营销策划方案
前言 在《 Elasticsearch 之(5)kibana多种搜索方式》中粗略提到高亮搜索的基本用法,本篇将详细剖析搜索结果的highlight高亮显示。 1、一个最基本的高亮例子建立mapping,设置IK分词器PUT /blog_website {"mappings": {&…...
做网站代理需要办什么执照/企业网站管理系统源码
密码错误频繁登录引发的”library cache lock”或”row cache lock”等待 对于正常的系统,由于密码的更改,可能存在某些被遗漏的客户端,不断重复尝试使用错误密码登录数据库,从而引起数据库内部长时间的”library cache lock”或”…...
四川建设网站公司/美工培训
实现这个效果你需要准备两张图片,一张小的,一张大用于鼠标经过时候显示。然后我们只要为img标签添加data-zoom-image属性,其值为大图的地址,最后在javascript中选择该图片调用elevateZoom()就可以了。下面给出一个例子(在github下…...
微信网站开发平台/一个产品营销策划方案
解决vscode出现两个光标的问题参考文章: (1)解决vscode出现两个光标的问题 (2)https://www.cnblogs.com/huahuayu/p/12235244.html 备忘一下。...