Android内存优化
内存优化 · 基础论 · 初识 Android 内存优化_最近一直在做内存和 anr 相关的优化,接下来我将会花几篇文章梳理一下内存相关的优-优快云博客
深入探索 Android 内存优化(炼狱级别)
https://juejin.cn/post/6844904099998089230
https://juejin.cn/post/6872919545728729095
性能
稳定性
1 handler的机制
一句话概括:looper不断获取MessageQueue中的一个message,然后交由handler来处理
1、handler封装消息的发送(主要包括消息发送给谁)
2、Looper——消息封装的载体。(1)内部包含一个MessageQueue,所有的Handler发送的消息都走向这个消息队列;(2)Looper.Looper方法,就是一个死循环,不断地从MessageQueue取消息,如果有消息就处理消息,没有消息就阻塞。
3、MessageQueue,一个消息队列,添加消息,处理消息
4、handler内部与Looper关联,handler->Looper->MessageQueue,handler发送消息就是向MessageQueue队列发送消息。
总结:handler负责发送消息,Looper负责接收handler发送的消息,并把消息回传给handler自己。
MessageQueue存储消息的容器。
处理过程:
从handler中获取一个消息对象,把数据封装到消息对象中,通过handler的send…方法把消息push到MessageQueue队列中。
Looper对象会轮询MessageQueue队列,把消息对象取出。
通过dispatchMessage分发给Handler,再回调用Handler实现的handleMessage方法处理消息。
流程图:
Handler的实现中适及以下对象:
1、Handler本身:负责消息的发送和处理
2、Message:消息对象
3、MessageQueue:消息队列(用于存放消息对象的数据结构)
4、Looper:消息队列的处理者(用于轮询消息队列的消息对象,取出后回调handler的dispatchMessage进行消息的分发,dispatchMessage方法会回调handleMessage方法把消息传入,由Handler的实现类来处理)
Message对象的内部实现是链表,最大长度是50,用于缓存消息对象,达到重复利用消息对象的目的,以减少消息对象的创建,所以通常我们要使用obtainMessage方法来获取消息对象
安全:Handler的消息处理机制是线程安全的
关系:创建Handler时会创建Looper,Looper对象的创建又创建了MessageQueue
2 view事件分发机制
Android事件分发流程如下:
Android事件分发顺序:Activity(Window) -> ViewGroup -> View
以上三个方法,均有boolean类型的返回值,通过设置true,false来控制事件传递的流程
Activity和View均没有事件拦截方法,是因为
1)、Activity作为事件响应起点,如果,Activity把事件拦截了,辣么将为导致整个屏幕都无法点击
2)、View作为事件响应的最末端,要么消费事件,要么不处理回传,没必要拦截事件
3 自定义view流程
为什么要自定义控件
1 特定的显示风格
2 处理特有的用户交互
3 优化我们的布局
4 封装等..
如何自定义控件
1 自定义属性的声明和获取
2 测量onMeasure
3 布局onLayout(ViewGroup)
4 绘制onDraw
5 onTouchEvent
6 onInterceptTouchEvent(ViewGroup)
4 listview和recyclerview区别,优缺点
1 Listview中ViewHolder是需要自定义的,在RecyclerView中ViewHolder是谷歌已经封装好的
2 Listview中的Item是只能垂直滑动的,RecyclerView可以水平滑动或者垂直滑动,针对多种类型条目的展示效果,如瀑布流 网格 支持多种类型
3 Listview中删除或添加item时,item是无法产生动画效果的,在RecyclerView中添加、删除或移动item时有两种默认的效果可以选择SimpleItemAnimator(简单条目动画) 和 DefaultItemAnimator(原样的条目动画)
首先总结下RecyclerView的特点:
1.支持不同方向,不同排版模式,实现多种展现数据的形式,涵盖了ListView,GridView,瀑布流等数据表现的形式
2.内部实现了回收机制,无需我们考虑View的复用情况
3.取消了onItemClick等点击事件,需要自己手动去写
5 view的绘制机制
View的绘制从ActivityThread类中Handler的处理RESUME_ACTIVITY事件开始,在执行performResumeActivity之后,创建Window以及DecorView并调用WindowManager的addView方法添加到屏幕上,addView又调用ViewRootImpl的setView方法,最终执行performTraversals方法,依次执行performMeasure,performLayout,performDraw。也就是view绘制的三大过程。
measure过程测量view的视图大小,最终需要调用setMeasuredDimension方法设置测量的结果,如果是ViewGroup需要调用measureChildren或者measureChild方法进而计算自己的大小。
layout过程是摆放view的过程,View不需要实现,通常由ViewGroup实现,在实现onLayout时可以通过getMeasuredWidth等方法获取measure过程测量的结果进行摆放。
draw过程先是绘制背景,其次调用onDraw()方法绘制view的内容,再然后调用dispatchDraw()调用子view的draw方法,最后绘制滚动条。ViewGroup默认不会执行onDraw方法,如果复写了onDraw(Canvas)方法,需要调用 setWillNotDraw(false);清楚不需要绘制的标记。
6 activity的启动流程
activity启动流程
我们可以从Context的startActivity说起,其实现是ContextImpl的startActivity,然后内部会通过Instrumentation来尝试启动Activity,这是一个跨进程过程,它会调用ams的startActivity方法,当ams校验完activity的合法性后,会通过ApplicationThread回调到我们的进程,这也是一次跨进程过程,而applicationThread就是一个binder,回调逻辑是在binder线程池中完成的,所以需要通过Handler H将其切换到ui线程,第一个消息是LAUNCH_ACTIVITY,它对应handleLaunchActivity,在这个方法里完成了Activity的创建和启动,接着,在activity的onResume中,activity的内容将开始渲染到window上,然后开始绘制直到我们看见
7 卡顿问题如何处理
卡顿的场景:
- UI的绘制。主要原因是绘制的层级深、页面复杂、刷新不合理,由于这些原因导致卡顿的场景更多出现在 UI 和启动后的初始界面以及跳转到页面的绘制上。
- 数据处理上。导致这种卡顿场景的原因是数据处理量太大,一般分为三种情况,一是数据在主线程处理,这个是初级工程师会犯的错误,二是数据处理占用 CPU 高,导致主线程拿不到时间片,三是内存增加导致 GC 频繁,从而引起卡顿。引起卡顿的原因很多,但不管怎么样的原因和场景,最终都是通过设备屏幕上显示来达到用户,归根到底就是显示有问题,所以,要解决卡顿,就要先了解 Android 系统的渲染机制。
Android系统的渲染机制核心工作原理的剖析:
1. 渲染流程的核心阶段
Android的UI渲染分为两个主要阶段:
-
应用层处理:负责View的测量(Measure)、布局(Layout)、绘制(Draw)。
-
系统层合成:通过SurfaceFlinger将多个Surface合成为最终帧,输出到屏幕。
2. 关键组件与机制
2.1 Vsync信号
-
作用:垂直同步信号(16ms触发一次,对应60Hz屏幕),协调渲染节奏,防止画面撕裂。
-
双重Vsync:
-
APP Vsync:触发UI线程开始处理View的绘制(measure/layout/draw)。
-
SurfaceFlinger Vsync:触发SurfaceFlinger合成图层并送显。
-
2.2 应用层绘制流程
-
Measure → Layout → Draw:
-
硬件加速(默认开启):绘制命令被记录到DisplayList(通过
RenderNode
),由渲染线程(RenderThread)转换为GPU指令。 -
软件绘制:直接通过CPU生成位图(Bitmap),效率较低。
-
-
Choreographer:协调Vsync信号与UI更新,确保在下一个Vsync到来时提交帧数据。
2.3 渲染线程与GPU
-
RenderThread:独立线程,负责执行GPU命令(如OpenGL/Vulkan),将DisplayList渲染为纹理,存入Graphic Buffer。
-
BufferQueue:生产者-消费者模型,应用作为生产者填充缓冲区,SurfaceFlinger作为消费者取出合成。
2.4 SurfaceFlinger合成
-
作用:管理多个窗口的Surface,合并后输出到屏幕。
-
合成策略:
-
硬件合成(HWC):优先使用GPU/显示处理器(如Overlay)高效合成。
-
GPU合成:当HWC无法处理时回退到GPU处理。
-
2.5 缓冲机制
-
双缓冲:使用前后两个缓冲区交替渲染和显示,避免画面撕裂。
-
三缓冲(Project Butter引入):减少卡顿,允许应用在错过一个Vsync后仍有缓冲区可用。
3. 渲染管线的时间线
-
UI线程:在APP Vsync触发后,处理用户输入、动画等,完成measure/layout/draw(需在16ms内完成)。
-
RenderThread:将DisplayList提交到GPU渲染,结果存入Graphic Buffer。
-
SurfaceFlinger:在下一个Vsync到来时,取出所有准备好的缓冲区进行合成,并送显。
4. 性能瓶颈与优化
-
掉帧原因:
-
UI线程耗时(如复杂布局)。
-
RenderThread渲染过长(如过度绘制)。
-
SurfaceFlinger合成超时。
-
-
优化工具:
-
Systrace:分析各阶段耗时。
-
GPU Profiler:检测过度绘制与GPU负载。
-
Hierarchy Viewer:优化布局层级。
-
5. 总结
Android渲染机制通过双重Vsync同步、硬件加速、多缓冲策略和分层合成,确保流畅的UI体验。开发者需关注主线程性能、GPU渲染效率及合成机制,避免过度绘制和布局嵌套,以提升帧率稳定性
- UI的过度绘制,绘制的页面有几层View,底层View都是隐藏的,这种的还绘制的话就会造成过度绘制
andriod卡顿优化方案
- 不要在主线程进行网络访问/大文件的IO操作
- 绘制UI时,尽量减少绘制UI层次;减少不必要的view嵌套,可以用Hierarchy Viewer工具来检测,后面会详细讲;
- 当我们的布局是用的FrameLayout的时候,我们可以把它改成merge,可以避免自己的帧布局和系统的ContentFrameLayout帧布局重叠造成重复计算(measure和layout)
- 提高显示速度,使用ViewStub:当加载的时候才会占用。不加载的时候就是隐藏的,仅仅占用位置。
- 在view层级相同的情况下,尽量使用 LinerLayout而不是RelativeLayout;因为RelativeLayout在测量的时候会测量二次,而LinerLayout测量一次,可以看下它们的源码;
- 删除控件中无用的属性;
- 布局复用.比如listView 布局复用
- 尽量避免过度绘制(overdraw),比如:背景经常容易造成过度绘制。由于我们布局设置了背景,同时用到的MaterialDesign的主题会默认给一个背景。这时应该把主题添加的背景去掉;还有移除 XML 中非必须的背景
- 自定义View优化。使用 canvas.clipRect()来帮助系统识别那些可见的区域,只有在这个区域内才会被绘制。也是避免过度绘制.
- 启动优化,启动速度的监控,发现影响启动速度的问题所在,优化启动逻辑,提高应用的启动速度。比如闪屏页面,合理优化布局,加载逻辑优化,数据准备,这里后面我会单独写一篇文章讲如何优化程序的启动速度及Splash页面设计,这里还会讲到热启动和冷启动.
- 合理的刷新机制,尽量减少刷新次数,尽量避免后台有高的 CPU 线程运行,缩小刷新区域。
andriod卡顿优化所用到的工具
性能问题并不容易复现,也不好定位,但是真的碰到问题就需要借助相应的的调试工具,下面介绍比较常用的调试工具。
- 1.Profile GPU Rendering
8 Android性能优化方法
一、UI渲染性能优化
1. 布局优化
-
减少布局层级
-
使用
ConstraintLayout
替代多层嵌套的LinearLayout/RelativeLayout
,布局复杂度从O(n²)降至O(n)。 -
通过
<merge>
标签合并重复布局,或<include>
复用公共布局。
-
-
避免过度绘制(Overdraw)
-
开启开发者选项中的**“显示过度绘制区域”**,蓝色为合格(1次绘制),红色需优化(4次+)。
-
移除不必要的
background
,或用Canvas.clipRect()
限定绘制区域。
-
-
异步加载复杂布局
-
使用
ViewStub
延迟加载非首屏视图,或AsyncLayoutInflater
异步解析布局。
-
2. 渲染流程优化
-
启用硬件加速
-
在
AndroidManifest.xml
中全局或按View启用硬件加速(API 14+默认开启)。
-
-
优化自定义View的
onDraw()
-
避免在
onDraw()
中创建对象(如Paint
、Path
),应提前初始化。 -
使用
Canvas.saveLayer()
谨慎,因其会触发离屏渲染(Offscreen Rendering)。
-
3. 列表滑动优化
-
RecyclerView优化
-
使用
DiffUtil
计算数据差异,避免notifyDataSetChanged()
全量刷新。 -
开启
setHasFixedSize(true)
避免重复测量。 -
预加载机制:通过
LinearLayoutManager.setInitialPrefetchItemCount()
预加载嵌套列表。
-
-
避免主线程耗时操作
-
图片加载使用
Glide
或Coil
,并配置磁盘缓存策略。
-
二、内存优化
1. 内存泄漏预防
-
常见泄漏场景
-
静态引用Activity/Fragment、未反注册监听器(如
BroadcastReceiver
)、Handler延迟任务。
-
-
工具检测
-
使用
LeakCanary
自动化检测,或通过Android Profiler的Memory Heap Dump分析。
-
2. 内存使用优化
-
Bitmap优化
-
根据控件大小采样加载(
inSampleSize
),使用RGB_565
格式(无透明度需求时)。 -
通过
BitmapPool
(Glide内置)复用Bitmap内存。
-
-
对象池化
-
高频创建的对象(如
Message
)使用obtain()
和recycle()
复用。
-
-
大型资源释放
-
页面销毁时释放数据库连接、文件流等资源。
-
三、启动速度优化
1. 冷启动优化
-
减少Application初始化
-
将非核心初始化(如第三方SDK)延迟到
SplashActivity
或异步线程。
-
-
主题优化
-
为启动Activity设置
windowBackground
为闪屏图,避免白屏/黑屏。
-
-
Multidex预加载
-
对5.0以下系统,通过
MultiDex.install()
优化Dex加载卡顿。
-
2. 延迟加载与异步化
-
使用
IntentService
或WorkManager
处理后台任务。 -
按需加载模块,结合
ClassLoader
动态加载非必要功能。
四、网络与存储优化
1. 网络请求优化
-
减少请求次数
-
合并API请求,使用
GraphQL
按需获取字段。 -
客户端缓存策略:
Cache-Control
、ETag
等。
-
-
数据压缩
-
使用Protocol Buffers替代JSON,开启GZIP压缩。
-
-
连接复用
-
OkHttp默认支持HTTP/2多路复用,避免重复TCP握手。
-
2. 存储优化
-
SharedPreferences优化
-
避免频繁
commit()
,优先用apply()
异步提交。 -
大文件存储改用
MMKV
或Jetpack DataStore
。
-
-
数据库优化
-
使用
Room
并开启索引,避免主线程查询。
-
五、耗电量优化
-
减少后台任务
-
使用
JobScheduler
或WorkManager
统一调度任务,避免频繁唤醒CPU。
-
-
传感器使用
-
及时注销GPS、加速度计等传感器的监听。
-
-
网络优化
-
批量上传日志、图片,减少移动网络下频繁切换基站。
-
六、工具与监控
-
Systrace
-
分析UI线程卡顿、RenderThread渲染耗时。
-
-
Android Profiler
-
监控CPU、内存、网络实时使用情况。
-
-
Layout Inspector
-
检查布局层级与属性冗余。
-
-
Firebase Performance Monitoring
-
线上监控App启动时间、网络请求延迟等核心指标。
-
七、代码层面优化
-
避免ANR
-
主线程耗时操作(如IO、密集计算)迁移到子线程。
-
-
数据结构选择
-
高频查询用
ArrayMap
/SparseArray
替代HashMap
。
-
-
减少反射与动态代码
-
反射调用比直接调用慢数倍,尽量避免。
-
总结
性能优化需结合**“预防-检测-修复”**三步走:
-
编码阶段遵循最佳实践(如异步化、内存复用);
-
通过工具定位瓶颈(Systrace、Profiler);
-
针对性优化(如布局层级简化、泄漏修复)。
建议建立性能监控体系(如APM系统),持续追踪核心指标,确保用户体验流畅稳定
10 strollview与list滑动冲突如何解决
自定义可适应ScrollView的ListView
就是要用ListView怎么办?那就只好自定义一个类继承自ListView、通过重写其onMeasure方法、达到对ScrollView适配的效果
11 常见的设计模式
单例模式或者工厂模式
12 ListView 优化
如何优化ListView的性能:
尽最大可能避免GC
滑动的时候不加载图片
将ListView的scrollingCache和animateCache设置为false
convertView重用;
利用好 convertView 来重用 View,切忌每次 getView() 都新建。ListView 的核心原理就是重用 View,如果重用 view 不改变宽高,重用View可以减少重新分配缓存造成的内存频繁分配/回收;
ViewHolder优化;
使用ViewHolder的原因是findViewById方法耗时较大,如果控件个数过多,会严重影响性能,而使用ViewHolder主要是为了可以省去这个时间。通过setTag,getTag直接获取View。
图片加载优化
如果ListView需要加载显示网络图片,我们尽量不要在ListView滑动的时候加载图片,那样会使ListView变得卡顿,所以我们需要在监听器里面监听ListView的状态,如果ListView滑动(SCROLL_STATE_TOUCH_SCROLL)或者被猛滑(SCROLL_STATE_FLING)的时候,停止加载图片,如果没有滑动(SCROLL_STATE_IDLE),则开始加载图片。
onClickListener处理(通过接口回传)
减少Item View的布局层级
这是所有layout都必须遵循的,布局层级过深会直接导致View的测量与绘制浪费大量的时间
adapter中的getView方法尽量少使用逻辑
不要在getView方法中做过于复杂的逻辑,可以想办法抽离到别的地方,
adapter中的getView方法尽量少做耗时操作
adapter中的getView方法避免创建大量对象
将ListView的scrollingCache和animateCache设置为false
分页加载数据
13 谈谈Binder机制
在Android启动的时候,Zygote进程孵化出第一个子进程叫SystemServer,而在这个进程中,非常多系统提供的服务。比方ActivityManagerSerivce, PowerManagerService等,都在此进程中的某一条线程上执行。
而非常多用户开发的应用程序。也就是我们常说的APP,基于安全的考虑,在安装到系统中的时候,都会被分配一个独特的UID。执行在一个单独的进程中。
基于Linux的用户安全机制。它们是没有办法直接訪问到上述系统服务的。
可是在实际中,App非常多时候是须要跟这些系统服务进行通信的,也就是要进行进程间通信。
而Binder机制则是Android系统实现进程间通信(IPC)的机制之中的一个
14 java虚拟机和android虚拟机的区别
Android中的Dalvik虚拟机相较于Java虚拟机针对手机的特点做了很多优化。
Dalvik基于寄存器,而JVM基于栈。在基于寄存器的虚拟机里,可以更为有效的减少冗余指令的分发和减少内存的读写访问。
Dalvik经过优化,允许在有限的内存中同时运行多个虚拟机的实例,并且每一个 Dalvik应用作为一个独立的Linux进程执行。
java虚拟机运行的是java字节码。(java类会被编译成一个或多个字节码.class文件,打包到.jar文件中,java虚拟机从相应的.class文件和.jar文件中获取相应的字节码)
Dalvik运行的是自定义的.dex字节码格式。(java类被编译成.class文件后,会通过一个dx工具将所有的.class文件转换成一个.dex文件,然后dalvik虚拟机会从其中读取指令和数据)
15 art和dalvik的区别
Dalvik与ART的区别
(1)在Dalvik下,应用每次运行都需要通过即时编译器(JIT)将字节码转换为机器码,即每次都要编译加运行,这虽然会使安装过程比较快,但是会拖慢应用以后每次启动的效率。而在ART 环境中,应用在第一次安装的时候,字节码就会预编译(AOT)成机器码,这样的话,虽然设备和应用的首次启动(安装慢了)会变慢,但是以后每次启动执行的时候,都可以直接运行,因此运行效率会提高。
(2)ART占用空间比Dalvik大(字节码变为机器码之后,可能会增加10%-20%),这也是著名的“空间换时间大法"。
(3)预编译也可以明显改善电池续航,因为应用程序每次运行时不用重复编译了,从而减少了 CPU 的使用频率,降低了能耗。
ART优点:
1. 系统性能的显著提升
2. 应用启动更快、运行更快、体验更流畅、触感反馈更及时
3. 更长的电池续航能力
4. 支持更低的硬件
ART缺点:
1. 更大的存储空间占用,可能会增加10%-20%
2. 更长的应用安装时间
16 功耗优化
以下是针对Android系统功耗相关技术点及面试要点的综合剖析,结合硬件、系统层、应用层优化策略及常见问题分析方法:
一、核心技术点剖析
1. 硬件层优化
-
低功耗处理器设计:通过流水线、超标量架构、动态电压频率调节(DVFS)等技术降低功耗。
-
摄像头模组与传感器:
-
功耗拆解公式:总功耗=平台基础功耗 + 屏幕 + 模组(AVDD/DVDD电路)+ 马达 + 算法 + 应用层开销。
-
硬件测试方法:飞线测试各电路电流,对比竞品机基准值。
-
-
屏幕与背光控制:根据场景动态调整亮度、分辨率,减少高刷新率屏幕的持续使用。
2. 系统层优化
-
电源管理策略:
-
DVFS:动态调整CPU/GPU频率和电压。
-
多核调度:关闭空闲核心,任务分配到低功耗核。
-
WakeLock管理:避免异常唤醒(通过
/sys/kernel/debug/wakeup_sources
排查)。
-
-
休眠机制:
-
验证系统是否进入VDD最小状态(
/sys/kernel/debug/rpm_stats
)。 -
灭屏后CPU进入WFI(Wait For Interrupt)状态,减少后台活动。
-
-
服务与广播管理:避免后台Service长期运行,优先使用
JobScheduler
或WorkManager
调度任务。
3. 应用层优化
-
代码效率:
-
避免短时临时对象(如用基本类型数组替代对象数组)。
-
使用
static final
常量减少类初始化开销。 -
避免浮点运算(比整型慢2倍)。
-
-
网络与I/O:
-
合并网络请求,使用HTTP缓存(如
HttpURLConnection
)。 -
数据库操作批处理+事务,及时关闭Cursor。
-
-
内存管理:
-
避免内存泄漏(如未注销的监听器、静态引用)。
-
使用
SparseArray
替代HashMap<Integer, Object>
,减少自动装箱开销。
-
4. 功耗评估与工具 178
-
Battery Historian:分析耗电分布、唤醒源、CPU状态。
-
高通平台分析:通过
/sys/kernel/debug/rpm_stats
和adb shell dumpsys batterystats
定位异常唤醒。 -
功耗模型:建立基准功耗(平台基础值 + 硬件组件功耗),对比实际测试值。
二、功耗高频面试要点
1. 常见优化策略
-
后台任务管理:
-
使用
IntentService
替代普通Service,任务完成后自动停止。 -
定位服务按需请求(如
FusedLocationProvider
结合地理围栏)。
-
-
UI与布局优化:
-
减少布局层级(用
ConstraintLayout
替代多层LinearLayout
)。 -
使用
ViewStub
延迟加载复杂视图。
-
-
算法与资源:
-
避免高复杂度算法(如频繁图像处理),采用低精度计算。
-
压缩资源文件,使用WebP格式图片。
-
2. 案例分析类问题 348
-
如何定位Camera高功耗?
-
测试各模式(预览/录像)功耗,对比竞品基准。
-
拆解硬件(模组AVDD/DVDD、马达电流)与软件(算法/美颜)贡献值。
-
优化策略:降低帧率、关闭非必要传感器(如激光对焦)。
-
-
ANR与卡顿的功耗关联:
-
主线程阻塞导致CPU长时间满载,触发温控降频,间接增加功耗。
-
3. 工具使用与日志分析 478
-
Battery Historian实战:
-
生成报告:
adb bugreport
+ 上传分析。 -
关键指标:
Partial Wakelock
持有时间、Mobile Radio
活跃周期。
-
-
唤醒源排查:
-
查看
dumpsys power
中的Wake Locks
和Suspend Blockers
。 -
通过内核日志定位异常中断(
msm_show_resume_irq
模块调试)。
-
4. 系统机制深入 19
-
Binder机制与跨进程通信:避免频繁跨进程调用(如ContentProvider)。
-
Handler与线程模型:子线程处理耗时任务,主线程减少阻塞。
三、进阶方向与趋势 17
-
AI驱动的动态优化:基于场景预测调整资源分配(如游戏模式自动升频)。
-
5G与功耗平衡:智能切换网络制式(如非活跃期降为4G)。
-
硬件协同设计:与芯片厂商合作定制低功耗模块(如NPU替代GPU计算)。
总结
面试中需结合具体场景(如短视频App优化),从硬件拆解、系统策略到代码细节层层递进。重点体现问题定位能力(如使用工具分析唤醒源)和综合优化思维(跨模块权衡)
17 ANR 的类型?如何避免?怎么分析解决?
在 Android 上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,
这个对话框称作应用程序无响应(ANR:Application Not Responding)对话框。用户可以选择让
程序继续运行,但是,他们在使用你的应用程序时,并不希望每次都要处理这个对话框。因此,在程
序里对响应性能的设计很重要,这样,系统不会显示 ANR 给用户。
Activity 5 秒 broadcast10 秒
耗时的操作 worker thread 里面完成, handler message…AsynTask , intentservice.等…
AN