App异常汇总与对策

UI交互异常

  1. 空显示/白屏
    1. 一般是因为数据为空或获取失败。要请产品定义加载中、加载失败、数据为空的UI。
  2. 显示不完整、错位
    1. 开发时考虑不同屏幕大小、窗体大小、内容量的兼容,做好对齐和层级的设置。内容量会引起折行、显示不全等问题。
    2. 如果有改变字体大小或多语言设置的需求,应在自测时确保最大字号和最长文字时显示正常。
  3. 格式显示错误。日期、时间、时区、数值、单位、语言等,请产品明确并准确实现。
  4. App启动或进入某界面的时间过长
    1. 耗时操作异步化,让用户更早看到程序界面
    2. 如果必须等某些操作后才好展示,让产品增加loading状态的UI
  5. 连续多次操作,数据异常。一般发生在异步操作的场景
    1. 连续点击按钮。请产品定义loading状态UI,重复点击不响应,或响应前点其它地方都是取消。
    2. 一个长时间的动画过程中执行反向操作,例如游戏开车前进时突然油门不松开地切成倒挡。需要程序做好兼容,请产品确认能不能这样操作,有什么后果。
  6. 异步结果返回时,用户已取消操作。一个极端情况是,服务器已处理了请求但网络正好断了,客户端没收到确认信息。
    1. 通常操作是不管的,下次进入或刷新就能看到最新状态。产品需要知道。
  7. 多个提示(Toast或自消失弹窗)没有依次显示。请产品定义:
    1. 如果提示都要在同一个地方显示,则做好全局管理,用队列做消息缓存,等前一个消息提示正常消失后,从队列取下一个来显示。不能让前一个立刻消失或被遮盖。
    2. 可以做排列显示,即下一个提示在前一个提示的下方,前一个提示消失时,下面的提示自动向上移动
  8. 卡顿
    1. 在UI操作的地方打印日志,分析出耗时操作。要么处理消息过多,要么处理某消息时间过长
    2. 调高UI相关线程的优先级,调低后台线程的优先级
    3. 用性能监控工具实时记录,分析出CPU或内存剧烈波动的操作
    4. 去掉主线程执行的IO操作
    5. 逐步剥离逻辑,定位出产生卡顿的部分。
  9. 换皮肤、配色方案
    1. 漏订阅消息
    2. 漏处理
  10. 图片、音视频不显示或不清晰
    1. 源文件的内容本身有问题
    2. 解码库的参数设置不对
    3. 缓存过小或被清理
    4. 系统不支持源格式的编解码
    5. 系统性能不足,跳帧,降低分辨率、帧率等
  11. 动画不播放
    1. 逻辑状态不对,或执行着多个操作
    2. 相关的View状态不对
  12. 用户体验问题,需求评审的时候就要提出了。别都推责给产品,东西是我们程序员做出来的,可以反向提要求。给三篇参考文章
    1. 需求评审的关注点
    2. 如何写出受技术欢迎的需求文档
    3. 程序员眼中最牛的UI设计师是怎样的?

网络异常

  1. 连接超时、读取超时、发送超时、对方断连/死连
    1. 设好网络库参数(成熟的网络库都有),长连接主动断开重连,短连接主动取消
    2. 和产品确认重试间隔时长,最大重试次数等
    3. 请产品定好相关UI提示
  2. 背压(后向压力,backpresure),数据消费者的处理速度低于数据生产者的生产速度。会造成UI呈现旧数据、数据队列拥塞最终内存耗尽
    1. 数据消费者
      1. 增大缓存,先缓存后处理
      2. 多线程处理
      3. 丢弃或合并处理部分数据
    2. 数据生产者
      1. 增加缓存,合并数据流,由【高频发少数据】变成【低频发多数据】
      2. 降低数据生产频率
      3. 丢弃部分数据。生产后,判断上次发送时间,未达指定时间间隔则丢弃
      4. 增大发送超时时间
  3. 网速波动:其它应用或模块在占用带宽,导致本功能超时
    1. 限速
    2. 主动停止不重要不紧急的网络任务,或降低优先级
    3. 不能对网速有预期,例如觉得1KB数据肯定秒级传完。都要考虑异常
  4. 信号弱,延时高,丢包
    1. 使用tcpdump+wireshark确认问题
    2. 选择更优的链路
  5. 后端
    1. 无响应,按超时处理
    2. 如约地返回错误,请产品定好UI提示
    3. 未定义地返回错误,例如响应体的JSON反序列化失败。catch exception,不能崩溃,日志做好记录,请产品定好提示,一般是直接toast出exception.message,必然的话做重试。

系统或硬件错误

  1. 资源被占用,初始化失败。例如文件、摄像头、端口、设备等已被别的线程、进程、应用打开。
    1. 可能被别的应用占用的资源,要做好打开失败的容错,有一定的UI提示,不能崩溃。
    2. 应用内的多线程/进程处理,应确保只有一个IO线程/进程,同一个资源的读写都在这个IO线程/进程内处理,其余线程/进程通过发消息来执行操作和传递数据。
  2. 无权限或动态申请权限失败。请产品设计做好用户不授权情况下的交互,不能崩溃。
  3. 串口
    1. 数据可能丢失或错乱,应用层协议要做好检验,例如CRC、MD5
    2. 发送或接收的单条电线可能断开,会产生“可接收但发送失败”的情况,得仔细检查
  4. 摄像头打开时间过长
    1. 硬件或系统层优化
    2. 预加载
    3. 请产品定义,用动画优化体感
  5. 摄像头打开异常
    1. 硬件或系统层
    2. 请产品定义,重试规则和用户交互提醒;
  6. 硬件松动。对应的程序异常时,检查硬件状态。
    1. 应用层断连,可以是网卡松了,网线被拔了,使用ifconfig查看网卡状态
    2. 黑屏,检查显卡或监视器连接状态,也可能屏幕电源没接上
  7. 工程样件硬件就是不可靠的
    1. 可以起一个线程,定时检测硬件状态,输入到日志,方便定位问题。
    2. 工程样件的芯片、CPU、GPU固件都可能有bug,可以怀疑到这一层。

SDK错误

  1. 版本不同
    1. 使用SDK都要经过真机自测
    2. 使用更新或更旧的SDK,尝试是否会出现问题
  2. 是否按预期工作,在不同场景下是否行为一致
  3. 处理流程或传参等错误,是否按文档做了
  4. 兼容性,用了当前系统不支持的API
  5. 三方库本身有bug,多加日志来确认。

程序错误

  1. 多个条件同时成立,导致UI或逻辑错误。复杂场景需要列一个表尽可能穷举所有情况,缺漏的请产品补充定义
  2. 死锁、死循环,直接导致ANR
  3. 在子线程调用了需要在主线程调用的方法
  4. C++野指针。用好STD或boost的便捷类
  5. 没有监听/订阅相关消息,状态改变不知道
    1. 确定监听/订阅是否存在重复
    2. 确定程序窗口销毁后停止相应的监听/订阅
  6. 参数未做配置,需要请产品确定默认值
  7. 内存(RAM)用尽,产生OOM
    1. 对大量级的数据进行流式读写,保持较少的数据量在内存中,更多部分仍在磁盘
    2. 检查内存泄漏,主要是排查需要手动release的对象,认真看说明文档
    3. 内存缓存需要限量,超过限额存入磁盘
    4. 用测试工具对复杂场景测一遍,长时间运行
    5. 大型对象慎用单例,不应该使用全局或静态变量保存
    6. 复用频繁创建销毁的对象
    7. 资源和对象及时释放
    8. 循环体内及时释放临时对象,极限情况可主动触发GC
  8. 磁盘(ROM)用尽
    1. 设计时考虑可能占用磁盘空间的数量,做好限额
    2. 产品设计上提供手动清理缓存的入口和缓存占用量的显示
    3. 数据缓存(例如媒体文件或日志)应做好滚动周期的限制,例如每次启动删除一个月前的数据
  9. CPU长时间占用过高
    1. 使用工具找出占用CPU的函数
    2. 使用工具查看UI渲染频率
  10. 切换到后台被杀掉或停止工作,回到前台需要恢复现场
  11. 认证信息过期而未检验,过期后未清理状态
  12. 外部存储器的文件丢失
  13. 外部存储器的文件被错误修改。解析的时候catch异常,无法恢复就删除或赋默认值
  14. 时序
    1. 是否按照预期的顺序执行
    2. 是否按预期的时机初始化完毕
  15. 数值错误
    1. 多线程/进程/应用,异步时序不对
    2. 没有加锁
    3. 共享空间写入乱序,包括内存和磁盘
    4. 异常退出,文件损坏。
  16. 线程过多。其中集中管理线程池。
  17. 背压,参考网络错误中的描述,同理。
  18. 反射操作错误

PS:不可能的异常

我们不是要处理所有的可能性,否则岂不是所有代码都要加try catch?

应该做的是在写代码前就确定可能有什么异常,有约定、协议、规范不会出错的,都不用做防御,在开发阶段最好就是通过崩溃来达成最高级别的警示。还可以加一些assert,在开发阶段澄清所有的异常。assert也可以防止别人错误地使用你的代码。

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

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

相关文章

Java基础(10)反射

Java反射是Java语言中的一个功能强大且复杂的机制,它允许程序在运行时访问、检查和修改它本身的结构(类、接口、字段、方法等)。反射机制主要在java.lang.reflect包中定义。 反射的核心组件 Class类:它的实例表示正在运行的Java…

【网站项目】高校推免报名

🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

K8s: Kubernetes扩展之自定义资源

自定义资源 自定义资源是 K8s 的扩展,有时候需要对K8s进行一个扩展在默认的K8s集群里面提供的资源对象是一个有限的集合比如常用的pod, deployment, service,这些都是K8s原生的资源之所以它资源,是因为它能够对外提供API接口变成一个resourc…

Java-异常处理-定义三角形类Triangle和异常三角形IllegalTriangleException类 (1/2)

任意一个三角形,其任意两边之和大于第三边。当三角形的三条边不满足前述条件时,就表示发生了异常,将这种异常情况定义为IllegalTriangleException类。 自定义异常类IllegalTriangleException: 当三角形的三条边不满足条件&#x…

[随记]Mac安装Docker及运行开源Penpot

下载Docker Desktop for Mac:https://www.docker.com/products/docker-desktop/ 安装Docker Desktop for Mac,安装完成后,启动Docker,然后在终端输入: docker version 在Mac电脑的Desktop,随便创建一个文…

零代码编程:用通义千问免费批量翻译英文文档

首先,在阿里云的dashScope灵积模型服务中,申请一个API-key,有挺多免费token的。 然后,在通义千问中输入提示词: 你是一个Python编程专家,现在要完成一个编写基于qwen-turbo模型API和dashscope库的程序脚本…

UML图(总结)

一、静态建模 1、类图: 展现了一组对象、接口、协作和它们之间的关系。 2、对象图 展现了某一时刻一组对象以及它们之间的关系。 3、用例图 展现了用例、参与者(Action)以及它们之间的关系。 二、动态建模 1、序列图(顺序图,时序图) 描述了以…

Android Handler用法

Android Handler用法 为什么要设计Handler机制?Handler的用法1、创建Handler2、Handler通信2.1 sendMessage 方式2.2 post 方式 Handler常用方法1、延时执行2、周期执行 HandlerThread用法主线程-创建Handler子线程-创建Handler FAQMessage是如何创建主线程中Looper…

云端芳华、运维之美

今天,在我们享受互联网服务带来的便利与高效的同时,有一群人默默地在幕后为我们提供支持,他们就是云端运维人员。 值此五一国际劳动节来临之际,我们要真诚感谢他们辛勤的劳动和奉献!

vue2集成ElementUI编写登录页面

目录 1. 整理目录文件: a. app.vue文件如下: b. Login.vue文件如下: c. router/index.js文件如下: d. 删除components中的文件: e. 最终项目目录整理如下: 2. 集成ElementUI编写登录页面 a. 安装ElementUI: b. 在main.js

springcloud自定义全局异常

自行创建一个实体类 /*** 全局异常处理类**/ ControllerAdvice public class GlobalExceptionHandler {ExceptionHandler(Exception.class) ResponseBody public Result error(Exception e){e.printStackTrace(); return Result.fail();}/*** 自定义异常处理方法* param e * re…

MyBatis-plus笔记——分页插件

插件配置 插件配置类,拦截器添加PaginationInnerInterceptor Configuration MapperScan("com.zxb.mp.mapper") // 扫描指定mapper接口路径 public class MyBatisConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisP…

2023-2024年汽车行业报告/方案合集(精选345份)

汽车行业报告/方案(精选345份) 2023-2024年 来源:2023-2024年汽车行业报告/方案合集(精选345份) 【以下是资料目录】 2023中国汽车科技50强 2023中国智能汽车产业发展与展望 2023比亚迪海豹汽车拆解报告 2023新能…

unity制作app(3)--gps定位

1.unity中定位Unity之GPS定位(高德解析)_unity gps定位-CSDN博客 代码需要稍微修改一下,先把脚本绑到一个button上试一试! 2.先去高德地图认证(app定位) 创建应用和 Key-Web服务 API | 高德地图API (ama…

[C++基础学习]----03-程序流程结构之跳转语句详解

前言 在C程序中,跳转语句break和continue是两种用于控制程序流程的关键字,常用于循环语句(如for循环、while循环)中。 正文 01-简介 1、break关键字: 当程序执行到break语句时,会立即跳出当前所在的循环&…

C#知识|汇总方法重载与静态方法应用技巧

哈喽,你好,我是雷工! 今天学习C#方法重载与静态方法应用技巧的相关内容。 01 方法重载有什么好处? 1.1、可以有效的减少类的对外接口(只显示一个方法比较简洁),从而降低类的复杂度。 1.2、方便…

【Vue 2.x】学习vue之二组件

文章目录 Vue二组件第五章es6文件导入出1、导出export 组件(component)1、定义2、模块化与组件化3、组件的分类1、非单文件组件非单文件三步骤创建组件标准写法简化写法组件的嵌套非单文件的不足之处 2、单文件组件vue单文件组件的使用脚手架创建项目重点…

C++@vscode配置C++开发环境常见问题和实践经验

文章目录 abstractvscode配置C/C开发环境常见问题 FAQC/C共用一组tasks.json/launch.json文件?关于配置文件中的注释更快地编译运行调试时调用外部终端控制台二次编译失败问题编译多个源文件😊源文件组织 编译出的可执行文件名中文乱码😊修改tasks.json…

Django框架之视图层

一、三板斧的原理介绍 1、HttpResponse 在Django中,HttpResponse是一个类,用于构建HTTP响应并返回给客户端。当视图函数处理完请求后,需要返回一个响应时,就会使用HttpResponse对象。 (1)创建HttpRespon…

C语言随笔集

注意 strlen 和 sizeof 的区别 strlen计算的是第一个 ‘\0’ 前面的字符的个数sizeof计算的是占用的内存空间的大小只和定义时有关C语言中,输出double类型(双精度)和float(单精度)时, 编译器默认精确到小数点后六位输出 默认输出的是6位小数,不足6位,以0补齐,超过6位按…