APP性能优化-稳定性(crash率)

APP性能优化-Memory
APP性能优化-稳定性(crash率)
APP性能优化-包体压缩
APP性能优化-CPU
APP性能优化-UI
APP性能优化-流畅度
前言

稳定性是衡量APP最重要的指标之一,当DAU达到百万、千万级,就算crash率只有0.1%崩溃次数也是不能接受的,维持低崩溃率是每个工程师应有的职责。

异常分类

在code的过程中,引发程序crash的原因大体分为两类:ErrorException,他们都继承Throwable

Throwable .png

Error

无法处理的错误,表示程序碰到较为严重的问题。大多数错误与上层的应用程序无直接关系。而是底层系统或是JVM(Java虚拟机)出现的问题。例如Java虚拟机运行错误(VirtualMachineError),当JVM内存空间不足时,将出现OutOfMemoryError。当Error出现后,上层程序是无法控制的,所以,出现这类错误时,本质上也是不应该试图去处理它所发生的异常状况。

Exception

Exception主要分为两大类Unchecked Exception(Runtime Exception)以及Checked Exception(非Runtime Exception)

Exception.png

Unchecked 与Checked 区别在于对于CheckedException,必须添加try…catch…捕获异常、或者throw 抛出异常并处理

//Checked Exception手动抛出异常
private void openFile() throws FileNotFoundException {
        File file = new File("");
        FileInputStream fileInputStream = new FileInputStream(file);
    }

//Checked Exception通过try...catch捕获
private void openFile() {
        File file = new File("");
        try {
            FileInputStream fileInputStream = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            //处理异常
        }
    }

UncheckedException,非强制性处理,在多线程环境下建议处理该异常,不然容易出现crash

//选择性异常处理,不强制
        try {
            List<String> list = new ArrayList<>();
            list.get(1);
        } catch (IndexOutOfBoundsException e) {
            //处理异常
        }

public E get(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

        return (E) elementData[index];
    }

随着APP高速迭代,维持低crash率是一场持久战,需要坚持。总结一下个人经验主要通过以下方法来维持低crash率
1.预防为主
2.针对性处理,由点到面
3.兜底、止损策略

1.预防为主

保证每个版本在发布之前都严格进行以下步骤
Lint扫描:Lint从多个维度以及可定义范围对工程进行扫描,可以对布局的合理性、代码结构、NPE、变量合理性等给出合理建议,如果能在每个版本发布之前都能处理掉Lint给出的扫描结果,那APP Crash率会有很大一部分提升

跑Monkey:经常能跑出APP的性能瓶颈,比如OOM、ANR等,及时去处理这些东西以免上线之后带来不必要的麻烦

2.针对性处理,由点到面

服务端脏数据处理:拿Rxjava来说,可以定义拦截器统一处理服务端数据格式、数据异常等,保证在回调给UI线程时是我们想要的数据。在使用服务端返回的数据时层级较多,在使用每一层时我们都要进行null判断,采取no believe server方式,服务端是不靠谱的,每一层都可能出现数据错误,不能因为数据问题导致APP Crash,这是最基本的。

数据格式问题:在页面功能复杂的时候,前端开发大部分不会手动去写数据结构,基本都是通过抓包工具抓取JSON然后再通过GsonFormat工具格式化得出数据结构。假设有个id字段是自增型的,在第一个版本数据量不多的时候后端返回的数据并未超过int范围,这时候Format出来的id将为int型(这里是个坑),当后续数据量变大之后id返回的值将超过int型,数据转换的时候必然会出现内存溢出导致线上大批量crash。对于类似这种可变数据长度,一定要注意。

ROM兼容性问题:Android是开源的,各个厂商都会修改源ROM变成有自己的ROM,这将导致平台兼容性问题。在某个版本,我们改变了APP日志投递策略为5分钟投递一次,通过Rxjava并发投递,上线之后在后台监控到很多华为手机上抛出的OOM问题,最终定位出是因为华为ROM对线程数量有限制,因为RxJava线程池是自增、无上限的线程操作突破线程上线是情理之中,后来我们通过自定义RxJava的线程池来解决这个问题

处理Unchecked Exception :在使用系统API或者第三方SDK时,一定要熟知文档,处理API可能手动抛出的Unchecked Exception

多线程引发的Exception :最常见的就是多线程同时操作List或者HashMap导致NPE问题,当确定数据结构会出现多个线程同时引用操作,尽量少用合理的数据结构去避免这个问题,比如说用Vector或者ConCurrentHashMap去替换保证线程安全性

3.兜底、止损策略

1、2两个步骤都不难,但贵在坚持,大部分APP是坚持不了的,还有就是 某些特定场景下才会导致的crash。有些crash会导致严重事故,这个不及时自损我们是承担不起的。两个方案:
热修复腾讯Tinker阿里AndFix,都是不错的方案,功能效果不一样,各有利弊,选择合适自己业务的框架就行

拦截器、降级策略:现在稍大一点的APP都会使用组件化,拿阿里的路由框架Aroute来说,我们可以在自定义拦截器中根据服务端模块配置策略对相应的模块进行降级处理,当用户点击跳转被降级的模块时可以采取跳转到H5RN、或者直接提示模块降级

强制版本升级:热修也有失灵的时候,Tinker在merge dex的时候有可能出现OOM可能导致热修失败,AndFix由于在JNI层改动由于ROM兼容性导致热修失败。这种时候就需要发小版本进行强制升级了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354