Android 性能优化之黑科技开道(一)

1. 缘起

在开发电视版智家 App9.0 项目的时候,发现了一个性能问题。电视系统原本剩余的可用资源就少,而随着 9.0 功能的进一步增多,特别是门铃、门锁、多路视频同屏监控后等功能的增加,开始出现了卡顿情况。

经过调研分析发现有一部分是日志输出导致的,profiler 工具显示有一个日志输出的线程会有频繁占用 CPU 时间片的现象。

2. 性能优化引起的 Android 日志开关控制问题及解决

2.1 查看日志线程的 CPU 占用率 

使用 Profiler 查看 CPU 占用率,在打开日志及关闭日志的情况下分别如下:

 (图 1 日志开关打开的情况)

 (图 2 日志开关关闭的情况下)

 由上可以看出,存在两个问题:

  1. 日志开关打开的情况下,占用 CPU 时间比较多

  2. 日志开关关闭的情况下,比打开的情况好一些,但还是会有一些 CPU 占用,通过打日志发现,是有一些日志没有关闭,还在频繁的继续打印

2.2 需要日志开关方案?

  1. 发现关不掉的 TAG 大部分第三方库中的,它们没有对外提供使能接口,导致日志关不掉,为了性能考虑,需要对第三方库中的日志进行控制,在必要时可以关闭它们;

  2. 如果线上的版本不关闭日志,会存在用户隐私或产品信息泄漏的风险,为了 APP 和用户安全考虑,需要关闭线上版本的日志输出;

  3. 另外,为了更加方便的发现错误,我们应该对日志级别进行控制,例如我们可以采用如下方案:无论任何时候都输出 E 级别日志,其它级别日志可以根据情况进行关闭;

 结论:我们需要一个统一关闭和控制所有日志的开关方案。

2.3 方案调研 

方案

方案介绍

优点

缺点

混淆

采用混淆 proguard 配置方式关闭 APP 日志输出,包括:

android.util.Log 类

java.io.PrintStream 类(java.lang.System.out.println( )和 java.lang.System.out.print()系列

实现简单,想关哪个关哪个

  1. 不能动态控制,版本一经编译就不能再更改了

  2. 在没有开启混淆的 App 上,需要先开启混淆,需要仔细调试保证没有问题

  3. 能控制 Java 层的日志输出,不能控制 Native 层

插桩+ASM

通过 AOP 编程,在日志输出的某个类中进行字节码插桩,实现控制日志输出的目的

灵活,稳定性高

  1. 实现复杂度较混淆要高

  2. 需要找到合适的适合插桩的点

Hook

通过反射或其它技术,针对日志输出的某一个实现点,进行 Hook,进而实现控制的目的

灵活,稳定性高

  1. 实现复杂度较混淆要高

  2. 需要找到合适的需要 Hook 的点和 Hook 技术

混淆

  1. 混淆方案有个缺点,就是不能通过开关动态的调节日志开关,先做为备选吧

 插桩

  1. 经过技术预研,发现插桩的方案如果选用 Transform, 只能修改自己写的类或者是第三方库中的类,而影响不到 Android SDK 中的类 android.util.Log

  2. 在暂时未找到其它插桩点的情况下,此方案行不通

 Hook

  1. 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 指令集相关,需要针对性汇编实现,稳定性较一般,技术门槛相对高

  1. 经过分析,发现

    1. Java 层的两种方案(反射+动态代理、ClassLoader 修改)不能满足我们的需求

    2. Native 的两种方案(GOT 和 inline hook)确实很强大,但在这里我们还用不到修改这么底层的内容

    3. 而 Xposed 框架类型的方案又太重

    4. 对比后发现,JniHook 正好能够满足我们的需求。Hook 并重定向 android.util.Log 类中的 native 方法(print_native)即可满足要求。

2.4 实现原理(对 Log 类进行 JniHook)

原理图:

2.5 最终效果

1. 通过我们的开关控制逻辑关闭了所有的 Java 日志,并保留 Error 级别的日志输出,如下图

2. 收益

  1. 提升了性能,CPU 占用率减少约 17%

  2. 有效防止了敏感信息泄漏,保护了用户隐私

  3. 使用自己的策略灵活管控了日志的输出

其它可以黑科技优化的方向是什么?下期敬请期待~

3. 团队介绍

「三翼鸟数字化技术平台-场景设计交互平台」主要负责设计工具的研发,包括营销设计工具、家电VR设计和展示、水电暖通前置设计能力,研发并沉淀素材库,构建家居家装素材库,集成户型库、全品类产品库、设计方案库、生产工艺模型,打造基于户型和风格的AI设计能力,快速生成算量和报价;同时研发了门店设计师中心和项目中心,包括设计师管理能力和项目经理管理能力。实现了场景全生命周期管理,同时为水,空气,厨房等产业提供商机管理工具,从而实现了以场景贯穿的B端C端全流程系统。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Apache DolphinScheduler 【安装部署】

前言 今天来学习一下 DolphinScheduler ,这是一个任务调度工具,现在用的比较火爆。 1、安装部署 1.0、准备工作 1.0.1、集群规划 dolphinscheduler 比较吃内存,所以尽量给 master 节点多分配一点内存,桌面和虚拟机里能关的应用…

P2249 【深基13.例1】查找 (二分)

题目链接 代码&#xff1a; #include<algorithm> #include<iostream> #include<cstring> #include<queue> #include<cmath>using namespace std; //就是找左端点&#xff0c;没有输出-1 int n; int q; int a[1000010];int main() {scanf("…

Qt QML的枚举浅用

QML的枚举用法 序言概念命名规则在QML定义枚举的规范 用法QML的枚举定义方法供QML调用的&#xff0c;C的枚举定义方法 序言 概念 QML的枚举和C的其实差不多&#xff0c;但是呢&#xff0c;局限比较多&#xff0c;首先不能在main.qml里定义&#xff0c;也不能在子项中定义。 …

Java入门教程||Java 多线程编程

Java 多线程编程 Java 给多线程编程提供了内置的支持。一个多线程程序包含两个或多个能并发运行的部分。程序的每一部分都称作一个线程&#xff0c;并且每个线程定义了一个独立的执行路径。 多线程是多任务的一种特别的形式。多线程比多任务需要更小的开销。 这里定义和线程…

晶核养号攻略,小白必读攻略!

晶核手游作为一款深受玩家喜爱的游戏&#xff0c;养号是玩家们在游戏中常常会碰到的问题之一。在这个攻略中&#xff0c;我们将为新手玩家们提供一些养号的建议和技巧&#xff0c;帮助他们更好地管理和提升自己的游戏账号。 1. 初始阶段的金币管理 在游戏初期&#xff0c;前60…

四信AI智能视频边缘分析盒+传感云平台,开启食品安全智慧监管新模式

方案背景 民以食为天&#xff0c;食品是人类生存必备的物质之一&#xff0c;食品生产安全关乎每个人的生命健康与社会可持续发展。在食品生产过程中&#xff0c;如何实现安全、健康生产是监管机构首要考虑因素&#xff0c;也是当今社会必须共同关注与努力的方向。 监管机构必…

C语言中的数组与函数指针:深入解析与应用

文章目录 一、引言二、数组的定义1、数组的定义与初始化2、char*与char[]的区别1. 存储与表示2. 修改内容3. 作为函数参数 三、字符串指针数组1. 定义与概念2. 使用示例3. 内存管理 四、从字符串指针数组到函数指针的过渡1、字符串指针数组的应用场景2、函数指针的基本概念3、如…

ETL工具-nifi干货系列 第八讲 处理器PutDatabaseRecord 写数据库(详细)

1、本节通过一个小例子来讲解下处理器PutDatabaseRecord&#xff0c;该处理器的作用是将数据写入数据库。 如下流程通过处理器GenerateFlowFile 生成数据&#xff0c;然后通过处理器JoltTransformJSON转换结构&#xff0c;最后通过处理器PutDatabaseRecord将数据写入数据库。如…

C++输出格式控制

setprecision(n)可控制输出流显示浮点数的数字个数。C默认的流输出数值有效位是6&#xff0c;所以不管数据是多少&#xff0c;都只输出六位。如果setprecision(n)与setiosflags(ios::fixed)或者setiosflags(ios_base::fixed)合用&#xff0c;可以控制小数点右边的数字个数。set…

4 月 8 日至 9 日 ICP Hacker House 邀你共赴 IC 生态项目开发新风口

为了更好地探索区块链技术前沿&#xff0c;体验作为全面智能合约云平台的互联网计算机&#xff08;Internet Computer Protocol&#xff09;&#xff0c;将数据、内容、计算和用户体验全部托管于链上&#xff0c;IC 生态致力于推动去中心化互联网的深度发展&#xff0c;并将更安…

OC分层渲染详解,OC分层渲染与云渲染区别

​OC分层渲染通过分层处理场景来提升渲染效率&#xff0c;而云渲染借助云服务器进行远程高性能渲染。主要差异在于OC分层渲染优化了本地渲染过程&#xff0c;云渲染则依靠云计算资源执行。 OC分层渲染是指什么 OC分层渲染&#xff0c;即Object Channel分层渲染&#xff0c;是一…

vue3中实现文本显示省略号和tooltips提示框

前言 在 B 端业务中&#xff0c;我们经常会遇到文本内容超出容器区域需显示省略号的需求。当鼠标移入文本时&#xff0c;会出现 Tooltip 显示完整内容。最近&#xff0c;我也遇到了这样的场景。为了提高业务通用性&#xff0c;我已将其封装为组件、Hook 和指令等形式供使用。 …

【浅谈面向过程和面向对象的区别】

面向对象和面向过程是两种不同的编程范式&#xff0c;它们在处理问题和构建软件时有着显著的区别。 一、面向过程 1、基本概念 面向过程编程是一种早期的程序设计范型&#xff0c;它以事件为中心&#xff0c;主要关注“怎么做”&#xff0c;即完成任务的具体步骤。它将问题分…

CTK插件框架学习-事件监听(04)

CTK插件框架学习-插件注册调用(03)https://mp.csdn.net/mp_blog/creation/editor/136989802 一、主要流程 发送者注册消息事件接收者订阅消息事件接收者相应消息事件 事件监听比插件接口调用耦合性更弱&#xff0c;事件由框架维护&#xff0c;不需要指定发送方和接收方 二、…

tensflow模型转onnx实践

一、基础知识介绍 1、TensorFlow介绍 TensorFlow™是一个基于数据流编程&#xff08;dataflow programming&#xff09;的符号数学系统&#xff0c;被广泛应用于各类机器学习&#xff08;machine learning&#xff09;算法的编程实现&#xff0c;其前身是谷歌的神经网络算法库…

WebGIS 之 Openlayer

1.导入第三方依赖 <link rel"stylesheet" href"https://lib.baomitu.com/ol3/4.6.5/ol.css"> <script src"https://lib.baomitu.com/ol3/4.6.5/ol.js"></script>2.初始化地图 初始化地图new ol.Map({}) 参数target:制定初始化…

阻塞队列(BlockingQueue)

何为阻塞队列 当阻塞队列是空时,从队列中获取元素的操作将被阻塞当阻塞队列是满时,往队列中添加元素将会被阻塞试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他线程往空的队列中插入新的元素试图往满的队列中,添加新的元素的线程也会被阻塞,直到其他线程从队列中移除…

基于SSM的社区疫情防控管理信息系统

目录 背景 技术简介 系统简介 界面预览 背景 随着时代的进步&#xff0c;计算机技术已经全方位地影响了社会的发展。随着居民生活质量的持续上升&#xff0c;人们对社区疫情防控管理信息系统的期望和要求也在同步增长。在社区疫情防控日益受到广泛关注的背景下&#xff0c…

OpenHarmony实战:Makefile方式组织编译的库移植

以yxml库为例&#xff0c;其移植过程如下文所示。 源码获取 从仓库获取yxml源码&#xff0c;其目录结构如下表&#xff1a; 表1 源码目录结构 名称描述yxml/bench/benchmark相关代码yxml/test/测试输入输出文件&#xff0c;及测试脚本yxml/Makefile编译组织文件yxml/.gitat…

Python基础之pandas:字符串操作与透视表

文章目录 一、字符串操作备注&#xff1a;如果想要全部行都能输出&#xff0c;可输入如下代码 1、字符检索2、字符转换3、字符类型判断4、字符调整5、字符对齐与填充6、字符检索7、字符切割8、字符整理 二、透视表1、pd.pivot_table2、多级透视表 一、字符串操作 备注&#xf…