Android常见异常与性能优化

1. ANR异常(Application Not Responsing:应用程序无响应的弹框)

(1) 原因:在主线程进行了耗时操作(如:网络IO操作、数据库操作或耗时计算等)

拓展:运行在主线程的操作如下,尽量避免在它们里面进行耗时操作。

  • Activity:Activity的所有生命周期回调运行在主线程(当然可在Activity生命周期回调中开启子线程执行耗时操作)
  • service:service运行在主线程(当然可在Service中开启子线程执行耗时操作,如封装好的IntentService内有一个工作线程用来处理耗时操作)
  • Broadcast:BroadcastReceiver的onReceive()回调运行在主线程
  • Handler:主线程中looper的Handler对象的handMessage()和post(runnable)方法运行在主线程
  • AsyncTask:AsyncTask回调中除了doInBackground()方法,其他回调(UI更新相关)都运行在主线程

(2) 解决ANR:主线程中避免耗时操作,让子线程执行耗时任务。可参考异步消息处理机制

  • Thread:创建子线程执行耗时操作
  • AsyncTask:抽象类AsyncTask派生出子类的doInBackground()方法来中执行耗时操作
  • HandlerThread:HandlerThread线程中创建Handler对象,在handleMessage()方法中执行耗时操作
  • IntentService:重写IntentService的onHandleIntent()方法执行耗时任务

2. OOM异常(Out Of Memory)

2.1 概念区分

  • 内存抖动:短时间内大量对象被创建又马上被GC释放,即频繁GC(垃圾回收)。瞬间产生的对象会严重占用内存区域,内存区域达到阀值时会触发GC回收掉不用的对象,导致刚刚产生的对象又被回收。
  • 内存泄漏:进程中的某些对象已经没有被其他地方引用,但是他们却可以直接或间接地引用其他没被回收的对象,导致GC无法产生作用。
  • 内存溢出(OOM):android系统会给每个安卓程序分配一定的内存,当程序所使用的内存超过最大值就会造成内存溢出,就是常说的OOM。

有些内存没有被释放从而失去控制,造成程序可使用的内存越来越少,系统运行速度减慢,严重情况下会导致程序崩溃,所以内存溢出是最严重的内存问题,必须解决。

备注:内存抖动或内存泄漏累积到一定程度都会造成内存溢出。

2.2 OOM原因

原因:当前占用的内存 + 我们申请的内存资源 > Dalvik虚拟机被分配的最大内存,常见于Bitmap大图加载时出现OOM。
备注:android系统会为每个应用程序分配一个独立的工作空间(即Dalvik虚拟机空间),使各个app运行互不影响;android系统为每一个Dalvik虚拟机设定了最大内存限制。

2.3 解决OOM

(1) Bitmap造成的OOM解决(Bitmap优化)

  • 大图压缩:根据压缩比(计算inBitmap属性值)获取缩略图
  • 图片显示:加载4类图片资源
  • 及时释放Bitmap内存:通过recycle()回调方法回收资源
  • 捕获异常(Error属性可以捕获到OOM,Exception属性捕获不到)

(2) 其他OOM解决

  • ListView(convertView复用 + 图片三级缓存机制LRU)
  • 避免在onDraw()方法里执行对象的创建(频繁GC,造成内存抖动,积累到一定程度导致内存溢出)
  • 谨慎使用多进程(使用复杂,同时使用不当会造成更多的内存溢出和程序错误,尽量不要使用)

3. Bitmap位图

4. UI卡顿

(1) UI卡顿原理
android系统每隔16ms就会触发一次页面渲染,若渲染成功(16内能完成相关计算),就更够达到每秒60帧(60fps)的流畅效果;若渲染不成功(16内不能完成相关计算:耗时操作、布局复杂、动画等原因),就会丢帧造成UI卡顿。
1秒渲染次数 = 1s/16ms =1000ms/16ms = 62.5次页面渲染。
(2) UI卡顿常见原因

UI卡顿原因 分析 优化 备注
UI线程做了轻微的耗时操作 严重将导致ANR 开启子线程做耗时操作 异步消息处理框架
布局layout过于复杂 无法在16ms内完成渲染 布局优化 -
布局层叠 导致View过渡绘制(某些像素在同一帧时间内被绘制多次) 布局优化 View频繁地触发measure(测量)和layout(摆放)方法,导致耗时过多及整个View频繁地重新渲染,从而使CPU或GPU负载过重
同一时间动画执行次数过多 导致CPU或GPU负载过重 合理地使用动画 动画虽效果好,但是更易造成性能要求
内存频繁触发GC(垃圾回收) 导致暂时阻塞渲染操作 - -
代码质量 冗余资源及逻辑等导致加载和执行缓慢 代码优化 -

5. 内存泄漏

6. 内存管理

(1) 内存管理 = 内存分配 + 内存回收
(2) android 进程优先级:前台进程 > 可见进程 > 服务进程 > 后台进程 > 空
备注:系统会先回收优先级低的进程。

7. 冷启动优化

8. 其他优化

(1) 尽量不要用静态变量存储核心数据
(2) 有关sharePreference的安全问题

  • 不能跨进程读写
  • 不能存储大数据:sharePreference以key\value的形式存储存储数据,存储过大数据易阻塞主线程,造成UI卡顿

(3) 内存对象序列化
(4) 避免在UI线程做繁重操作

你可能感兴趣的:(Android常见异常与性能优化)