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…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
