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端全流程系统。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【蓝桥杯嵌入式】RTC——实时时钟

一、RTC简介 RTC RTC—real time clock,实时时钟,主要包含日历、闹钟和自动唤醒这三部分的功能,其中的日历功能我们使用的最多。日历包含两个32bit的时间寄存器,可直接输出时分秒,星期、月、日、年。 从Cubemx里的配置…

HTTPS传输过程

HTTPS:超文本传输安全协议 相较于HTTP明文传输,HTTPS增加了SSL/TLS进行了加密增加了通信的安全性。 SSL和TLS是两个不同的加密方法,SSL是TLS的前身,现在绝大多数浏览器使用的是TLS,所以着重了解以下TLS的概念即可。 首…

接口测试之测试原则、测试用例、测试流程......

一、接口的介绍 软件测试中,常说的接口有两种:图形用户接口(GUI,人与程序的接口)、应用程序编程接口(API)。 接口(API)是系统与系统之间,模块与模块之间或者…

Open3D(C++) 法向量精细化处理

目录 一、算法原理1、原理概述2、参考文献二、代码实现三、结果展示1、平滑前1、平滑后本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。

在集群中使用deepspeed如果端口被占用可以使用deepspeed参数更改

在集群中使用deepspeed如果端口被占用可以使用deepspeed参数更改 这一次G老师不好使了 在集群中使用deepspeed默认的端口号29500被占用,显示更改居然不起作用 G老师给的方法也不好使 #!/bin/bash MASTER_ADDRlocalhost MASTER_PORT29501 # 选择一个未被占用的端…

C++ 11是如何封装Thread库的?

引言 C11 标准引入了一个重要的特性,即原生线程支持,这标志着C语言在并发编程领域迈出了坚实的步伐。在此之前,开发人员在进行跨平台的多线程编程时,不得不依赖于操作系统提供的特定API,如Windows API或POSIX Threads…

接口调用成功后端却一直返回404

vuespringboot 我在vue.config.js中配置了向后端的反向代理 然后使用了axios向后端发送post请求 可以看到可以接收到前端传来的值 但是前端控制台却报了 “xhr.js:245POST http://localhost:7777/api/login 404 (Not Found)” 最后询问我那智慧的堂哥... ... 解决办法是把C…

《QT实用小工具·五》串口助手

1、概述 源码放在文章末尾 该项目实现了串口助手的功能,可在界面上通过串口配置和网络配置进行串口调试。 基本功能 支持16进制数据发送与接收。支持windows下COM9以上的串口通信。实时显示收发数据字节大小以及串口状态。支持任意qt版本,亲测4.7.0 到…

即将截稿 CCF-A多媒体顶会ACM MM‘24 北京时间4月9日提交摘要

会议之眼 快讯 第32届ACM MM (ACM MULTIMEDIA)即国际多媒体会议将于 2024 年 10月28 -日11月1日在澳大利亚墨尔本隆重举行!MM是由ACM(Association for Computing Machinery,计算机协会)主办的国际性学术会议,是计算机…

Docker,anaconda环境的部署与迁移

功能上线将提上日程,但是如何将我windows环境下的程序放到linux服务器的测试环境跑通呢?这是我这整个清明假期将要解决的一件事,最蠢的办法就是看自己的环境下有哪些依赖,如何到服务器上一个一个下,但是首先这个方法很…

Day79:服务攻防-中间件安全IISApacheTomcatNginx弱口令不安全配置CVE

目录 中间件-IIS-短文件&文件解析&蓝屏&写权限 HTTP.SYS(CVE-2015-1635)主要用作蓝屏破坏,跟权限不挂钩 IIS短文件(iis全版本都可能有这个问题) IIS文件解析 IIS写权限 中间件-Nginx-文件解析&目录穿越漏洞&CRLF …

DFS(基础,回溯,剪枝,记忆化)搜索

DFS基础 DFS(深度优先搜索) 基于递归求解问题,而针对搜索的过程 对于问题的介入状态叫初始状态,要求的状态叫目标状态 这里的搜索就是对实时产生的状态进行分析检测,直到得到一个目标状态或符合要求的最佳状态为止。对于实时产生新的状态…

天猫双十一美妆销售数据分析-Python数据分析项目

文章目录 项目介绍关键词 一、读取数据一、读取数据二、数据清洗2.1 重复数据处理2.2 缺失值处理2.3 提取表格中有用信息并新增为列 三、数据探索3.1 各品牌SKU数3.2 品牌总销量和总销售额3.3 各类别的销售量、销售额情况3.4 各品牌热度3.5 各品牌价格3.6 男性护肤品销量情况3.…

Vuex的模块化管理

1:定义一个单独的模块。由于mutation的第二个参数只能提交一个对象,所以这里的ThisLog是个json串。 2:在Vuex中的index.js中引入该模块 3:在别的组件中通过...mapState调用模块保存的State的值。 4:用...mapMutations修…

基于php医院预约挂号系统

摘 要 随着信息时代的来临,过去的管理方式缺点逐渐暴露,对过去的医院预约挂号管理方式的缺点进行分析,采取计算机方式构建医院预约挂号系统。本文通过阅读相关文献,研究国内外相关技术,开发并设计一款医院预约挂号系统…

【逆向思考 】【拓扑排序】1591. 奇怪的打印机 II

本文涉及的知识点 逆向思考 拓扑排序 LeetCode1591. 奇怪的打印机 II 给你一个奇怪的打印机,它有如下两个特殊的打印规则: 每一次操作时,打印机会用同一种颜色打印一个矩形的形状,每次打印会覆盖矩形对应格子里原本的颜色。 一…

活动回顾丨掘金海外,探寻泛娱乐社交APP出海新风口

3月中旬,Flat Ads携手声网、XMP在广州成功举办“泛娱乐社交APP出海新风口——广州站”的主题线下沙龙活动。 多位大咖与泛娱乐社交APP赛道的行业伙伴汇聚一堂。本次活动邀请到Flat Ads 市场VP 王若策、声网娱乐视频产品负责人 陈际陶、XMP资深产品运营专家 屈俊星等多位行业大…

材料物理 笔记-4

原内容请参考哈尔滨工业大学何飞教授:https://www.bilibili.com/video/BV18b4y1Y7wd/?p12&spm_id_frompageDriver&vd_source61654d4a6e8d7941436149dd99026962 或《材料物理性能及其在材料研究中的应用》(哈尔滨工业大学出版社) 离…

Stable Diffusion扩散模型【详解】小白也能看懂!!

文章目录 1、Diffusion的整体过程2、加噪过程2.1 加噪的具体细节2.2 加噪过程的公式推导 3、去噪过程3.1 图像概率分布 4、损失函数5、 伪代码过程 此文涉及公式推导,需要参考这篇文章: Stable Diffusion扩散模型推导公式的基础知识 1、Diffusion的整体…

OpenHarmony实战:小型系统移植概述

驱动主要包含两部分,平台驱动和器件驱动。平台驱动主要包括通常在SOC内的GPIO、I2C、SPI等;器件驱动则主要包含通常在SOC外的器件,如 LCD、TP、WLAN等 图1 OpenHarmony 驱动分类 HDF驱动被设计为可以跨OS使用的驱动程序,HDF驱动框…