Android应用开发岗 面试汇总-性能优化篇

2022-04-07  本文已影响0人  hahaoop

背景

最近在准备面试,结合之前的工作经验和近期在网上收集的一些面试资料,准备将Android开发岗位的知识点做一个系统的梳理,整理成一个系列:Android应用开发岗 面试汇总。本系列将分为以下几个大模块:
Java基础篇Java进阶篇常见设计模式
Android基础篇Android进阶篇性能优化
网络相关、数据结构与算法
常用开源库、Kotlin、Jetpack

注1:以上文章将陆续更新,直到我找到满意的工作为止,有跳转链接的表示已发表的文章。
注2:该系列属于个人的总结和网上东拼西凑的结果,每个知识点的内容并不一定完整,有不正确的地方欢迎批评指正。
注3:部分摘抄较多的段落或有注明出处。如有侵权,请联系本人进行删除。

性能优化篇只做概述,详细优化方案参考链接中的文章即可

1 启动速度优化

前置知识点:APP启动流程、Activity启动流程

优化方向
Google给出了启动加速的方向:

1.1 替换Application的主题

1、当APP启动时,会先于Main Thread展示一个空白的window,此时,可以通过给Application设置特定的主题,即展示一个图片,用到的是theme中的windowBackground属性。

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:windowBackground">@mipmap/launch</item>   //闪屏页图片
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowContentOverlay">@null</item>
</style>

2、再在Activity的onCreate方法中,先于super.onCreate()把正常的主题替换回来。


image.png

1.2 代码逻辑优化

1.3 使用耗时统计工具

1.4 冷启动耗时统计

1.4.1 adb命令 :

adb shell am start -S -W 包名/启动类的全限定名 。-S 表示重启当前应用

C:\Android\Demo>adb shell am start -S -W com.example.moneyqian.demo/com.example.moneyqian.demo.MainActivity
Stopping: com.example.moneyqian.demo
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.moneyqian.demo/.MainActivity }
Status: ok
Activity: com.example.moneyqian.demo/.MainActivity
ThisTime: 2247
TotalTime: 2247
WaitTime: 2278
Complete

1.4.2 系统日志 :

在AS中的Logcat中,过滤关键字:ActivityTaskManager: Displayed(华为系统关键字不同),可以看到当前启动的activity以及耗时,如:

image.png

参考链接

2 布局优化

根据Google官方出品的Android性能优化典范60帧每秒是目前最合适的图像显示速度,事实上绝大多数的Android设备也是按照每秒60帧来刷新的。为了让屏幕的刷新帧率达到60fps,我们需要确保在时间16ms(1000/60Hz)内完成单次刷新的操作(包括measure、layout以及draw),这也是Android系统每隔16ms就会发出一次VSYNC信号触发对UI进行渲染的原因。

2.1 帧率,丢帧

2.2 过渡绘制

原色 – 没有过度绘制 – 这部分的像素点只在屏幕上绘制了一次。
蓝色 – 1次过度绘制– 这部分的像素点只在屏幕上绘制了两次。
绿色 – 2次过度绘制 – 这部分的像素点只在屏幕上绘制了三次。
粉色 – 3次过度绘制 – 这部分的像素点只在屏幕上绘制了四次。
红色 – 4次过度绘制 – 这部分的像素点只在屏幕上绘制了五次。

2.3 过渡绘制优化方案

过渡绘制需要结合业务,适当的进行优化

2.4 使用GPU配置渲染工具

2.5 其他优化方案

使用标签,Merge减少嵌套层次、ViewStub延迟初始化。

参考链接

3 内存优化

内存优化,即对出现内存的问题进行解决。Android中常见的内存问题包括:

3.1 内存泄露

内存泄露的本质,即短生命周期的对象被长生命周期对象引用,导致不能被回收。
解决方案:

3.2内存溢出

Android系统的每个进程都有一个最大内存限制,如果申请的内存资源超过这个限制,系统就会抛出OOM错误。
解决方案:

@Override
    public void onTrimMemory(int level) { //level有多个值,具体略
        super.onTrimMemory(level);
    }

3.3 内存抖动

解决方案:

4 卡顿

出现卡顿的原因:当界面刷新无法保证60fps时,导致丢帧的情况,给用户的感知就是卡顿。
出现卡顿的情况:

解决方案:

5 ANR

5.1 ANR的分类:

5.2 ANR的发生原因:

5.3 ANR日志分析:

当发生ANR的时候Logcat中会出现提示

04-06 15:58:46.215 23480-23483/com.example.testanr I/art: Thread[2,tid=23483,WaitingInMainSignalCatcherLoop,Thread*=0x7fa2307000,peer=0x12cb40a0,"Signal Catcher"]: reacting to signal 3
04-06 15:58:46.364 23480-23483/com.example.testanr I/art: Wrote stack traces to '/data/anr/traces.txt'

ANR的Log信息保存在:/data/anr/traces.txt,每一次新的ANR发生,会把之前的ANR信息覆盖掉。如:

04-01 13:12:11.572 I/InputDispatcher( 220): Application is not responding:Window{2b263310com.android.email/com.android.email.activity.SplitScreenActivitypaused=false}.
5009.8ms since event, 5009.5ms since waitstarted
04-0113:12:11.572 I/WindowManager( 220): Input event 
dispatching timedout sending 
tocom.android.email/com.android.email.activity.SplitScreenActivity

04-01 13:12:14.123 I/Process( 220): Sending signal. PID: 21404 SIG:3---发生ANR的时间和生成trace.txt的时间
04-01 13:12:14.123 I/dalvikvm(21404):threadid=4: reacting to signal 3 ……
04-0113:12:15.872 E/ActivityManager( 220): ANR in com.android.email(com.android.email/.activity.SplitScreenActivity)
04-0113:12:15.872 E/ActivityManager( 220): Reason:keyDispatchingTimedOut  -----ANR的类型
04-0113:12:15.872 E/ActivityManager( 220): Load: 8.68 / 8.37 / 8.53 --CPU的负载情况
04-0113:12:15.872 E/ActivityManager( 220): CPUusage from 4361ms to 699ms ago ----CPU在ANR发生前的使用情况;备注:这个ago,是发生前一段时间的使用情况,不是当前时间点的使用情况;

04-0113:12:15.872 E/ActivityManager( 220): 5.5%21404/com.android.email: 1.3% user + 4.1% kernel / faults:
10 minor
04-0113:12:15.872 E/ActivityManager( 220): 4.3%220/system_server: 2.7% user + 1.5% kernel / faults: 11
minor 2 major
04-0113:12:15.872 E/ActivityManager( 220): 0.9%52/spi_qsd.0: 0% user + 0.9% kernel
04-0113:12:15.872 E/ActivityManager( 220): 0.5%65/irq/170-cyttsp-: 0% user + 0.5% kernel
04-0113:12:15.872 E/ActivityManager( 220): 0.5%296/com.android.systemui: 0.5% user + 0% kernel
04-0113:12:15.872 E/ActivityManager( 220): 100%TOTAL: 4.8% user + 7.6% kernel + 87% iowait----注意这行:注意87%的iowait
04-0113:12:15.872 E/ActivityManager( 220): CPUusage from 3697ms to 4223ms later:-- ANR后CPU的使用量
04-0113:12:15.872 E/ActivityManager( 220): 25%21404/com.android.email: 25% user + 0% kernel / faults: 191 minor
04-0113:12:15.872 E/ActivityManager( 220): 16% 21603/__eas(par.hakan: 16% user + 0% kernel
04-0113:12:15.872 E/ActivityManager( 220): 7.2% 21406/GC: 7.2% user + 0% kernel
04-0113:12:15.872 E/ActivityManager( 220): 1.8% 21409/Compiler: 1.8% user + 0% kernel
04-0113:12:15.872 E/ActivityManager( 220): 5.5%220/system_server: 0% user + 5.5% kernel / faults: 1 minor
04-0113:12:15.872 E/ActivityManager( 220): 5.5% 263/InputDispatcher: 0% user + 5.5% kernel
04-0113:12:15.872 E/ActivityManager( 220): 32%TOTAL: 28% user + 3.7% kernel

从Logcat中可以得到以下信息:

注:并不是所有的ANR类型都有章可循,很多偶发的ANR受限于当时发生的环境或者系统Bug;因此对ANR,更应该强调预防而不是分析

5.4 ANR触发场景

链接

6 网络优化

如果不正确的使用网络,可能带来一些问题,包括:

解决方案:
网络优化主要从三个方面进行:1. 速度;2. 成功率;3. 流量。

7 电量优化

电量优化的一般套路:

8 Apk瘦身

8.1 代码瘦身

8.2 资源瘦身

8.3 So瘦身

针对用户机型分布保留特定架构的So;当前主流手机都是使用arm64-v8a(第 8 代、64 位 ARM 处理器),因此在实际开发中,进行如下配置即可:快速解决适配 64 位 App 的一个痛点

android {
      defaultConfig {
            ndk {
                    abiFilters 'armeabi-v7a', 'arm64-v8a'
            }
     }
}

链接

9 正确的异步姿势

参考

上一篇 下一篇

猜你喜欢

热点阅读