当前位置: 首页 > news >正文

转载-android性能优化

android性能优化

Reason: Broadcast of Intent { act=android.intent.action.TIME_TICK

ActivityManager: 
ANR in com.***.***
PID: 16227
Reason: Broadcast of Intent { act=android.intent.action.TIME_TICK flg=0x50000014 (has extras) }

有那么一段时间我被这个ANR折磨到每天吃不下饭睡不着觉日渐憔悴,Read the fucking source code,每天看android源码各种跟踪调试编译烧写之后,终于找出了问题所在,应用层APP的UI线程刷新太频繁!

不要使用Html.fromHtml()

Textview里的文字设置多种颜色时不要偷懒,分两个Textview来写,使用Html.fromHtml加载时会耗时500+毫秒,用多了引起卡顿。

Handler传参尽量要使用基础类型

msg.obj传递java类对象在1秒400次频率下会导致数据丢失卡顿,并且会莫名其妙出现数据错乱。

UI线程一定要只做刷新UI动作

UI线程最好只做界面相关的动作,不要为了偷懒少些几行代码就把整个数据抛给UI线程,并发大的时候会丢失数据。
数据的各种格式和逻辑要在子线程中判断,把不需要刷新UI的数据拦截下来并抛掉,总之就是不要频繁刷新UI。

EventBus不适合高并发数据的处理,老老实实写接口用回调吧

在实现一些设计模式上EventBus更有用,但在高并发数据下即使加了eventBusIndex处理速度还是慢,并且会越来越慢。

定时任务不要用timer,使用Handler的sendEmptyMessageDelayed()或sendMessageDelayed()

timer耗费的资源多,并且一旦异常之后就会把整个任务终结掉出现各种难以预料的问题。

jni回调java函数时,一定要去冗余数据

jni层把有用数据过滤精简之后再回调java函数,1000毫秒回调400多次根本刷新不过来。

JNI DETECTED ERROR IN APPLICATION: JNI SetByteArrayRegion called with pending exception 'android.view.ViewRootImpl$CalledFromWrongThreadException' thrown in unknown throw location

刚开始遇到这个错误我以为jni层SetByteArrayRegion这个地方byte数组copy出错,单独调试jni的库也一点问题没有。最后感觉这个地方又有view又有Thread,那么会不会是在jni的子线程里调用了UI线程导致,十几个从jni回调上来的地方一个一个地方排查,果然是在callback线程直接更新UI所致!一个地方遗漏掉了,同事以为我改了,我以为他改了,结果谁都没改,因为板子没接收音机的模块,CAN总线没有发收音机的数据上来,这个模块一直没调试过,直到被测试发现之后叼了我们一顿。信息同步很重要啊!

Skipped *** frames! The application may be doing too much work on its main thread.

场景是不停的用handler定时发delay message,然后分发给UI来跑界面,模拟真实使用场景,跑了一夜,第二天又卡又慢,这个问题不用到处搜索了,写的清清楚楚明明白白

The application may be doing too much work on its main thread

只能看自己的代码调试看看耗时操作,逐个场景分析。我这里是因为真实数据是在子线程分发出去,然后个UI线程获取数据之后再用Handler来更新UI,但是因为模拟分发数据,为了图方便用了handler的sendMessageDelayed函数,所以相当于主线程分发数据之后,UI线程又开一个Handler又在主线程中刷新数据,造成不必要开销。解决方法就是,加一个开关,如果是模拟数据,直接更新UI不再发handler更新UI。

android.view.InflateException: Binary XML file line # *: Error inflating class

自定义view库在另外一个功能,通过compile project的方式引入,然后在项目工程的layout文件里直接按照包名类名来引入,总是报这个错误,包名类名路径都正确,很郁闷,一般也不会怀疑一个经过各种验证的自己写好的封装view库,但是原因就在这里。

@RequiresApi(api = Build.VERSION_CODES.N)
public MyView(Context context, AttributeSet attrs, int defStyleAttr)

为了调用新接口构造函数加了的API版本,而运行的机器低于这个版本,所以在xml里配置这个view的时候就会报错,这个地方调用低版本的API,去掉版本限制就OK了,RequiresApi要慎用。

优化内存

1、所有的HashMap尽量改ArrayMap
2、所有的enum尽量改成static变量
3、所有xml布局层级嵌套超过3层精简一下
4、所有的for或while循环里,尽量避免new对象除非逻辑如此
5、所有for或while避免使用Iterator或者for(Object obj:list)形式便利,直接用最原始语句遍历
6、onDraw()里不要new对象
7、能用jpg的图就不要用png,jpg的图质量最低压缩比例最高,网上搜索一下jpg和png压缩工具,压缩图片大小
8、所有fragment,特别是主界面里的,改成用时加载不用时销毁,不再一直加载,容易被回收
9、编译时剪裁系统应用主要在./build/target/product下,利用find语句查找并注释删减应用,在注释时,# Launcher2 \要把连接符\直接删除掉,否则注释语句相当于/** Launcher2 \ 后面的一长串代码 **/

find . -type f -name '*' | xargs grep 'Launcher2'
find . -name '*' | xargs grep dalvik.vm.heapsize

10、内存相关

adb remount
adb shell
mount -o remount rw /systemdumpsys meminfo
adb shell dumpsys meminfo com.***.***
adb shell dmesg
adb shell cat /proc/kmsg
adb shell procrank
//查看应用启动时间
adb shell am start -W com.***.***/com.***.***.MainActivityVSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)USS - Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)

修改framework层应用内存阈值大小在./frameworks/native/build
下,比如android:largeHeap="true"时,调整内存到512m

PRODUCT_PROPERTY_OVERRIDES += \dalvik.vm.heapstartsize=8m \dalvik.vm.heapgrowthlimit=64m \dalvik.vm.heapsize=512m \dalvik.vm.heaptargetutilization=0.75 \dalvik.vm.heapminfree=512k \dalvik.vm.heapmaxfree=8m

11、固定应用方向,使android:screenOrientation="reverseLandscape"无效,固定在某个方向,修改frameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindowManager.java
源文件

@Overridepublic int rotationForOrientationLw(int orientation, int lastRotation) {if (false) {Slog.v(TAG, "rotationForOrientationLw(orient="+ orientation + ", last=" + lastRotation+ "); user=" + mUserRotation + " "+ ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED)? "USER_ROTATION_LOCKED" : ""));}if (mForceDefaultOrientation) {return Surface.ROTATION_0;}

修改为固定旋转180度

@Overridepublic int rotationForOrientationLw(int orientation, int lastRotation) {if (false) {Slog.v(TAG, "rotationForOrientationLw(orient="+ orientation + ", last=" + lastRotation+ "); user=" + mUserRotation + " "+ ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED)? "USER_ROTATION_LOCKED" : ""));}if (mForceDefaultOrientation || true) {return Surface.ROTATION_180;}

12、删减系统服务
在frameworks/base/services/java/com/android/server/SystemServer.java中删减服务, 这里也是启动SystemUI的地方

相关文章:

转载-android性能优化

android性能优化 Reason: Broadcast of Intent { actandroid.intent.action.TIME_TICK ActivityManager: ANR in com.***.*** PID: 16227 Reason: Broadcast of Intent { actandroid.intent.action.TIME_TICK flg0x50000014 (has extras) }有那么一段时间我被这个ANR折磨到每…...

笔记 | Clickhouse命令行查询

在 ClickHouse 中,可以使用命令行客户端执行查询。默认情况下,ClickHouse 的命令行客户端称为 clickhouse-client。下面是一些基本的步骤和示例,用于使用 clickhouse-client 进行查询。 首先,需要确保已经安装了 ClickHouse 服务…...

Dockerfile-xxxx

1、Dockerfile-server FROM openjdk:8-jdk-alpine WORKDIR /app COPY . . CMD java -Xms1536M -Xmx1536M -XX:UseG1GC -jar -Dlog4j2.formatMsgNoLookupstrue -Dloader.pathresources,lib -Duser.timezoneGMT-05 /app/server-main-1.0.0.jar 2、Dockerfile-bgd #FROM openjdk…...

Vue中的$attrs

今天产品经理要求做保留某组件全部功能,还要在它的基础上增加东西。如果不嫌麻烦的话就笨办法,但是想一下怎么只用少量代码高效的二次封装组件呢 Vue中的$attrs 在 Vue2 中,attr 是指组件接收的 HTML 特性(attribute),通过 prop…...

使用阿里云的oss对象存储服务实现图片上传(前端vue后端java详解)

一:前期准备: 1.1:注册阿里云账号,开启对象存储oss功能,创建一个bucket(百度教程多的是,跟着创建一个就行,创建时注意存储类型是标准存储,读写权限是公共读)…...

python实例100第32例:使用a[::-1]按相反的顺序输出列表的值

题目:按相反的顺序输出列表的值。 程序分析: a[n:-n]作用是去除前n个元素和末n个元素a[-n]作用是取倒数第n个元素a[:-n]的作用是去除后n个元素a[::-1]的作用是将所有元素逆序排列a[n::-1] 的作用是从第n个元素截取后逆序排列 程序…...

python执行脚本的时候获取输入参数

当我们执行脚本的时候,通常都会执行 python test.py -i xxx -o xxx,这里的 -i 和 -o 都是输入参数,这到底是怎么传递的呢? 本文纯粹记录一下 import argparseif __name__ __main__:print("hello")# 创建AugumentParser…...

Halcon指定区域的形状匹配

Halcon指定区域的形状匹配 文章目录 Halcon指定区域的形状匹配1.在参考图像中选择目标2.创建模板3.搜索目标 在这个实例中,会介绍如何根据选定的ROI选择合适的图像金字塔参数,创建包含这个区域的形状模板,并进行精确的基于形状模板的匹配。最…...

Linux——常用命令

1、命令的基本格式 对服务器来讲,图形界面会占用更多的系统资源,而且会安装更多的服务、开放更多的端口,这对服务器的稳定性和安全性都有负面影响。其实,服务器是一个连显示器都没有的家伙,要图形界面干什么&#xff…...

外包干了2个月,技术反而退步了...

先说一下自己的情况,本科生,19年通过校招进入广州某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…...

洛谷C++简单题练习day6—P1830 城市轰炸

day6--P1830 城市轰炸--1.26 习题概述 题目背景 一个大小为 nm 的城市遭到了 x 次轰炸,每次都炸了一个每条边都与边界平行的矩形。 题目描述 在轰炸后,有 y 个关键点,指挥官想知道,它们有没有受到过轰炸,如果有&a…...

【linux-interconnect】What NVIDIA MLNX_OFED is?

NVIDIA MLNX_OFED Documentation v23.07 - NVIDIA Docs 文章目录 What NVIDIA MLNX_OFED is?Overview[Software Download](https://docs.nvidia.com/networking/display/mlnxofedv23070512#src-2396583107_NVIDIAMLNX_OFEDDocumentationv23.07-SoftwareDownload) Wh…...

Unity开发中的XML注释

在Unity开发中&#xff0c;XML注释主要用于C#脚本的注释&#xff0c;以帮助生成代码文档和提供IntelliSense功能。以下是一些关于如何使用XML注释的技巧&#xff1a; 创建注释&#xff1a; 在C#中&#xff0c;XML注释是由///或/**...*/开始的。例如 /// <summary> /// 这…...

[MQ]常用的mq产品图形管理web界面或客户端

一、MQ介绍 1.1 定义 MQ全称为Message Queue&#xff0c;消息队列是应用程序和应用程序之间的通信方法。 如果非要用一个定义来概括只能是抽象出来一些概念&#xff0c;概括为跨服务之间传递信息的软件。 1.2 MQ产品 较为成熟的MQ产品&#xff1a;IBMMQ&#xff08;IBM We…...

JWT令牌(JSON Web Token)

目录 1 前言 2 JWT令牌的组成 3 使用步骤举例 3.1 pom.xml中引入依赖 3.2 JWT生成 3.3 JWT验证 4 实践中的使用举例 4.1 拦截非法访问 4.1.1 编写为工具类 4.1.2 下发给用户 4.1.3 编写拦截器 4.1.4 注册拦截器 4.2 获取相关数据提升效率 1 前言 在我们编写的后端…...

华硕ASUS K43SD笔记本安装win7X64(ventoy为入口以支撑一盘多系统);友善之臂mini2440开发板学习

记录 老爷机 白色 华硕 K43SD 笔记本 安装 win7X64 1. MBR样式常规安装win7X64Sp1 (华硕 K43SD 安装 win7X64 ) 老爷机 白色 华硕 K43SD 笔记本 安装 win7X64 (常规安装) 设置: 禁用UEFI 启用AHCI ventoy制作MBR(非UEFI)方式的启动U盘 U盘中放cn_windows_7_ultimate_wit…...

npm设置源(原淘宝源域名已过期)

今天打包机器报错&#xff0c; Couldnt find package "antd-mobile2.3.4" required by "neo-ui-mf-base1.0.41" on the "npm" registry. 找不到antd mobile的包&#xff0c;查看源发现淘宝域名npm.taobao.org 和 registry.npm.taobao.org 域名…...

操作系统-进程通信(共享存储 消息传递 管道通信 读写管道的条件)

文章目录 什么是进程通信为什么进程通信需要操作系统支持共享存储消息传递直接通信方式间接通信方式 管道通信小结注意 什么是进程通信 分享吃瓜文涉及到了进程通信 进程通信需要操作系统支持 为什么进程通信需要操作系统支持 进程不能访问非本进程的空间 当进程P和Q需要…...

NODE笔记 2 使用node操作飞书多维表格

前面简单介绍了node与简单的应用&#xff0c;本文通过结合飞书官方文档 使用node对飞书多维表格进行简单的操作&#xff08;获取token 查询多维表格recordid&#xff0c;删除多行数据&#xff0c;新增数据&#xff09; 文章目录 前言 前两篇文章对node做了简单的介绍&#xff…...

Scikit-Learn 高级教程——自定义评估器

Python Scikit-Learn 高级教程&#xff1a;自定义评估器 Scikit-Learn 提供了许多内置的评估器&#xff08;Estimator&#xff09;来进行机器学习任务&#xff0c;但在某些情况下&#xff0c;我们可能需要自定义评估器以满足特定需求。本篇博客将深入介绍如何在 Scikit-Learn …...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...

Vue3中的computer和watch

computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...