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

兼容性低概率系统问题记录性能/体验问题

鸿蒙

使用弹窗报错:class constructor cannot called without 'new'

解决办法:

把@Entry

@Component

改成@CustomDialog

并加上

controller: CustomDialogController;

安卓

  1. dialog设置高度MATCH_PARENT全屏后,三星机型和好像是一加,会带出顶部状态栏,设置隐藏状态栏属性无效。

  2. 解决方法:高度不设置为MATCH_PARENT,通过windowmanager.getdefaultdisplay来获取并设置高度,再设置dialog的窗口属性,使状态栏不占位window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

  3. 折叠屏适配

比较多的是折叠展开后,宽度没适配,view展示不全,一般是在onconfigchange回调里面监听宽度变化,然后去重新刷一下ui。

八特有的机型,比如好像是vivo,需要在AndroidManifest.xml里面加screensize,有的时候会收不到监听,比如dialog里面的onconfigchange在息屏时收不到,这个时候如果业务过于复杂还拿不到activity,可以context.registerconfigchange,这样dialog的onconfigchange就能收到了。还有如果这个时候直接去拿屏幕宽度也可能拿不准的,最好用onconfigchange回调的宽度,这个回调的是px单位的宽度。

  1. 荣耀机型繁体字的逗号会自动居中。已知问题,无需解决。

  2. 连续出来2个dialog,有个dialog会多出一截白色view。解决方法:只弹一个

  3. 业务bug01:想使用drawerlayout,但是发现在页面上无法侧滑出来,因为drawerlayout有个长按屏幕编译可以出来抽屉然后可拖拽出抽屉的属性,尝试修改它的感知区域,修改后发现drawerlayout拦截的是整个页面的事件。。。尝试页面diapatch处拦截事件给drawerlayout失败,因为无法判断页面内部是否有其他滚动的子view,安卓的apid不中啊。后面尝试使用viewpager实现drawerlayout的效果,因为层级放得不对,切到有的业务后那些业务直接把左右滑事件吃掉以后没有恢复导致侧滑功能再失效。后面从业务角度换了一个层级解决。

  4. 业务bug02-超低概率:页面上可见的appid与系统最高的appid不一致,导致startactivity出问题,业务bug。未解决

  5. 业务bug03-超低概率:使用fragment时,使用commitAllowingStateLoss去创建替换fragment,正常是oncreate->ui创建与加载->ondestroy。出问题的时候是oncreate->ondestroy->ui创建与加载,view创建时通过context拿不到资源或者view.xxx失败闪退,然后被线上检测到异常闪退。推测是commitAllowingStateLoss导致,可以尝试使用commit修复。该问题,未解决

  6. 业务bug04-特定场景必现bug:空传参导致程序崩溃,该场景正好是退出一个进程的页面加上又被try catch住了所以事情发生的没有闪退或其他异常表现,只是再进页面的时候是空白的一个页面,再次进页面的时候进程重启+页面重新创建所以没看出什么问题,只能看到页面没创建出来,然后发生问题的地方出现在一个线程池里面。。。线程池链接到了下一个进程的页面创建的地方,出现整个页面渲染不出来的问题。解决方法:缓存时给个默认值减少空值发生,再加个判空,概率低了很多,不过还是有超超超低概率出现页面渲染失败空白的问题。

  7. ViewPager2。常用的无限循环,一般处理方式就是getItemNumber的时候返回一个Integer.MAX,达到无限循环的目的,如果是一页一页翻过去的那没啥问题,如果是scrollto某一页,中间跨度很大很大,比如差了几十个item,那么就会肉眼可见的卡顿,原因:scrollto的时候会拿总列表数去生成东西,这个时候会造成内存抖动,解决方法不使用Integer.MAX,getItemNumber设置成比较大的数字即可,比如10000啥的。

其他

  1. ios os16以下,识别链接时汉字为黑色方块。解决方法:直接干掉链接中的汉字。或者尝试编码后再识别链接。

  2. uniapp,url跳转失败,链接过长导致,干掉一些携参。古早问题,不知道现在还有问题没。

  3. 鸿蒙。 不能instanceof接口。解决方法,使用父类或者判断这个接口的特定方法是否存在。

  4. 依然鸿蒙,如果静态方法里面裹静态方法,静态方法里面用到了子类,这个时候会报父类没有构造,然后运行白屏。解决方法,这段代码变成普通方法,不要用static修饰。

  5. 依然鸿蒙,listdatasource数据改变时通过for循环数据通知到ui渲染,但是比如有一个length=5的数组,循环到了index=2、3就没有继续循环下去了,无异常发生,列表view展示不全,只能展示1、2、3个view,后面发现是重复渲染,应该是循环上了,再ondisappear的时候把该业务标志位置为默认值即可。

  6. 依然鸿蒙,grid拖拽补位组件,如果用了lazyforeach,拖拽回调的接口index是乱的,导致删除的不是预期的item。不用lazyforeach,列表数量太大时,比如超过80个item,拖拽明显卡顿。解决方法:根据官网lazyforeach的计算算法,反推出正常的index,但是我没试哈。后面应该是限定了展示数据最多不超过多少个。未解决

  7. 公司跨端组件,动态计算css样式的动画,如果反复进退页面展示这个动画,安卓端会明显的这个动画越来越卡,最后闪退,可能是框架的动画或者native没有反注册该跨端组件导致的内存泄漏,未解决

影响体验的性能问题:

内存泄露/内存抖动/OOM、启动首帧耗时、卡顿、包体积、fps、兼容性问题、保活

1.耗时操作有哪些?

耗时操作:

1)rpc、网络请求、数据库操作、文件读写、IO、file、进程间通信、编解码

2)sp(commit同步耗时,apply异步大数据频繁读取耗时)、图片加载、嵌套布局、复杂布局、动态计算也有可能、线程切换、加锁卡顿、解析大型数据、AB开关、注册kmp、短时间生成大量对象

解决方法:

不同问题有不同的解决方式,一般是放子线程/异步调用,动画铺平,框架解,mkkv减少一次内存切换,减少页面布局层级或者xml的布局写到java代码里面放首帧后,有一点点耗时但是不是很耗时的更改调用时机放首帧后,

之前遇到过:

主线程new file。

低端车机煲机多媒体应用8小时,视频播放卡顿严重,音视频不同步。一个是性能带不起来,一个是时间戳的差异越来越大

网络请求(弱网)

应用启动的时候切线程去用bitmapfactory加载了一次image,导致冷启时用户肉眼可见的空白了几百毫秒,还是高端机。其实这里放主线程比较好,因为这里不是大图加载,切线程对用户的影响可能更大一些。

AB开关,组件化的时候在类似于应用启动时高性能静态加载资源的地方使用了AB开关

下游业务使用kmp,注册下游业务的时候启动耗时又增加了,拎到首帧后线上又出来anr,因为kmp链接到了tecal

给xml里面多加了一层布局,首帧耗时增加几十ms。。。

为了实现复杂动画,动态计算css,导致安卓大部分中/低端机动画掉帧非常严重。公司的跨端组件跑不起来复杂动画。为什么要动态计算而不是帧动画?当然是动画太复杂只能根据业务规则来计算。。。

跟手滑的时候使用translateX,整个页面掉帧。。。

日志打印,一些常调用遍历调用的地方加日志多了容易卡。

2.包大小

怎么优化?

在不影响用户体验的情况下进行优化,压缩。

图片、资源压缩。图片可以使用ImageOptim压缩、安卓使用webp压缩、内置lottie资源找视觉压缩,基本能压很多。

代码绘制样式图片、动效。以便减少内置图片大小和减少图片加载时的空白时间。

资源改成线上资源。画不出来再尝试线上资源,图片、lottie、字体、视频

压缩xml文件。

删除无用/已下线功能代码

优化日志打印

代码裁剪。裁剪一些so库的代码只留有用到的资源,比如:ffmpeg。一些app没那么多动态化需求就没有必要引入跨端组件或者小程序的一些库了。

3.Fps

1)一般是大列表有这个问题,解决方法

滑动时列表停止add数据,等列表滑动停止再add数据

分页加载、懒加载、差分更新

2)背地里偷偷做微耗时操作,或者每个item去做微耗时操作。微耗时参考耗时操作

3)频繁生成对象,gc

4)频繁重绘ondraw,这个会引起屏幕频繁刷新,每次都是软件到硬件的一次刷新

5)内存泄露、越来越严重、gpu带不起来

6)view层级太多。滑动时超重,如translateX啥的。view层级太多也会导致首帧耗时慢的问题。

7)动画掉帧,改大fps

4.保活

双进程守护、service守护

5.内存泄露

1)内存泄漏的情况:

单例模式。

静态变量持有的引用导致的内存泄露。

非静态内部类(包括匿名内部类)默认就会持有外部类的引用,当非静态内部类对象的生命周期比外部类对象生命周期长时,就会内存泄露,比如常见的Handler,Thread,AsyncTask,创建一个线程去作网络请求。

未取消注册或回调导致的内存泄漏。

集合中的对象未清理造成内存泄漏。

资源未关闭或未释放导致内存泄漏,比如流对象、流式RPC、WebView、地图等使用完后要及时关闭。

Handler造成的内存泄漏

线程造成的内存泄漏

地图、视频播放器、图片加载、webview、流式数据停止使用或者退出页面的时候没有反注册。

也不一定是页面,如果一个列表每个item都去注册一次webview,但是item不可见或者销毁的时候没有反注册,也可能会导致后面的数据渲染不出来。

2)表现

程序异常(case by case)

程序越使用内存占用越大且内存占用增长较快

频繁GC但是内存得不到有效的释放

因为频繁的GC和生成对象和内存碎片化界面响应越来越慢

界面渲染卡顿、滑动卡顿或者view组件渲染不出来又不报错、白屏

最终OOM闪退

3)怎么避免?

记得反注册

合理使用缓冲策略

使用weakrefrence

及时释放资源,如流式数据、webview

避免静态集合无限制增长

4)内存泄漏原理

创建一个对象,也就是在堆区里申请多一块空间给它,如果某个对象一直持有这块空间,该空间无法得到释放。所以如果内存泄露的次数多,最终很容易引起内存溢出。

程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费。

对象在引用链上,但是已经不可用了。根可达,但是内存已经不能再用了。

5)内存泄漏检测原理

jvm判断对象应该被回收的方式:

引用计数法

当对象没有其他对象在引用该对象时,应该被回收。

可达性分析

GC roots(静态变量、线程栈变量、常量池、JNI指针)

在GC roots的引用链上可以找到对象的时候,就认为这个对象根可达,GC来回收时发现该对象根可达,该对象就不应该被回收。在引用链找不到该对象,该对象不可达,就应该被回收。

6)怎么检测?

自己可以用MAT,俩Ativity跳来跳去,比较heap堆栈,过滤掉弱引用虚引用啥的就是泄漏的方法

平时线下检测LeakCanary,主要是hook页面生命周期,hook生命周期这种操作也可以用来检测白屏。

7)LC原理和步骤

原理:可达性分析。根可达但无用。利用 WeakReference + ReferenceQueue 来检测对象是否应被回收。

8)LC不能用于线上的原因

LeakCanary 会主动GC、Dump内存快照,造成卡顿和ANR,只适合开发阶段,不能用于线上。

频繁gc造成掉帧卡顿

dump内存快照耗时会造成anr

hprof上传文件太大,耗时耗流

重复dump,手机内存爆满

9)koom

检测思路跟LC差不多,线上可以使用这个监控内存泄漏。

不同的是触发方式、gc时机不同、分析方式,还要可以检测native泄漏和thread泄漏。

koom不主动 GC,不阻塞主进程。内存占用率 >= 80% && 连续检测超过3次时,fork一个子进程去异步分析dump文件,卡也只卡子进程,且本地分析以后只把分析结果上传到服务器。

6.兼容性问题、多语言适配、RTL

一般是互联网app机型兼容性问题。

安卓原生就是多种安卓机型,不同安卓os版本和不同厂商之间,这种一般跟fwk和硬件有关。主要是分辨率和系统bug。

字体粗细、分辨率适配(宽、窄、大屏、2折叠、3折叠、上下折叠)、繁体字逗号自动居中、view倾斜后有锯齿、不同机型屏幕展示的字体不一样、同一个数值但是view字体大小表现不一致、时不时带出个导航栏、白边

如果是跨端就是在安卓兼容性问题上叠加不同类型的os之间,比如安卓/ios/鸿蒙之间。

iOS os 16以下识别链接时汉子识别出来是黑块、有的表情符安卓展示不出来显示一个方块。

更多的是双端差异和跨端容器实现不一致。lottie不设置宽度的时候双端表现不一致,一个填充所有,一个按照lottie素材内部宽度来展示。两帧动画衔接处有差异。

ios不保留第一帧的状态,第2帧开始前会回到初始坐标,需要marginTop来矫正。

安卓保留最后一帧状态,但是第2帧的初始坐标是第一帧的坐标,安卓需要在动画里translateY来矫正

http://www.jsqmd.com/news/1355561/

相关文章:

  • 上海本地防水补漏服务商推荐,解决房屋各类渗漏问题 - 海棠依旧大
  • 数字孪生十年回顾与未来展望我们正在经历什么我们正在经历什么
  • 2026年盐城实体商家必读:收银系统选型避坑指南 - 微城市网络
  • Kubernetes安全检测:使用BOtB识别与验证Service Account密钥的方法
  • 2026程序员转型指南:AI浪潮下,如何抓住百万级岗位机遇?
  • Llama-3.1-8B-Instruct-w4a16模型评估全攻略:GSM8K基准测试与结果解读
  • 【YOLOv11模型改进系列】42 可变形卷积DCNv4:让YOLOv11的卷积核学会“变形”,专治各种不规则目标
  • 如何快速上手HAL模型?5分钟完成RNA剪接分数预测的完整教程
  • 2026最新培训视频总结口碑推荐 | 筛选整理后的实用选择建议
  • 高中化学系统学习法:从零构建知识网络与解题模型
  • 艾奇在线的AI搜索优化服务具体产品类型详解 - 产业观察报
  • 开源Agent管理平台ooderAI架构与实践指南
  • Java毕业设计:构建英语学习激励小程序的完整业务闭环
  • 工业AI智能体安全架构:三层护栏设计原理与实战
  • 数字孪生开发者生存指南AI时代你的技能树该往哪点
  • 深入SGI STL源码:从内存池到红黑树,掌握C++标准库设计精髓
  • UE5运行时虚拟纹理实战:动态热力图的性能优化方案
  • Garage Web UI:重新定义分布式存储管理的可视化解决方案
  • 提升计算机科学论文检索效率:aspire-biencoder-compsci-spec实战案例
  • CentOS Stream 9部署OpenClaw:轻量级告警通知网关对接企业微信机器人实战
  • 5分钟终极指南:用Win11Debloat快速清理Windows系统,免费重获流畅体验
  • 2026年不走弯路的易普森防爆伺服电机厂家挑选逻辑:五大实战案例暴露出的致命盲区与破局 - 品牌报告
  • 2026年物流第三方比价平台哪个便宜靠谱?看完这篇不踩坑 - 快递物流资讯
  • 【YOLOv11模型改进系列】43 Ghost卷积:让YOLOv11在移动端跑出云端的速度
  • Muse Code:终端编程智能体实战指南,提升开发效率
  • 芜湖市弋江区GEO服务商代理加盟选型靠谱推荐:本地合伙人怎么判断合作价值? - 企业新闻快传
  • 终极指南:Boltz-2如何实现生物分子结构预测与结合亲和力分析
  • STC8G1K08A单片机ADC实战指南:从寄存器配置到滤波算法与硬件设计
  • UFold性能评测:188.29G FLOPs如何实现比传统工具快10倍的预测速度
  • 郑州男士纹眉去哪?管城区这家工作室,打造自然英气眉形 - 优企甄选