瘦身"/>
Android性能优化之异常处理应用瘦身
简介
常见的异常无非就是ANR和OOM,掌握如何避免这两种异常有助于提升应用性能。另外,应用瘦身虽然不是性能的优化,而是app的优化,所以也放到这篇文章一起分享。
异常处理
ANR
原因
简述一下哪些地方是主线程:
- Activity的所有生命周期回调
- Service默认执行在主线程
- BroadCastReceiver的onReceiver回调
- 没有使用子线程的looper的handler的handlerMessage(),post(Runnable)方法
- AsyncTask的回调,除了donInBackground方法,其他都是在主线程
ANR就是程序无响应异常(Application Not Responding)
在主线程中做了耗时操作,容易出现ANR
- 一般的主线程对输入事件处理超过5S
- 主线程在执行BroadCastReceiver的onReceiver()方法时,超过10S
- 主线程在执行Service的各个生命周期函数时超过20S未处理完毕
- 耗时的网络访问
- 大量的数据读写
- 数据库操作
- 硬件操作(比如camera)
- 调用thread的join()方法、sleep()方法、wait()方法或者等待线程锁的时候
- service binder的数量达到上限
7.service忙导致超时无响应 - 其他线程持有锁,导致主线程等待超时
- 其它线程终止或崩溃导致主线程一直等待。
方案
- 避免在主线程执行耗时操作,所有耗时操作应新开一个子线程完成,然后再在主线程更新UI。
- UI线程尽量只做跟UI相关的工作
- 耗时的工作(比如数据库操作,I/O,网络操作),采用单独的工作线程处理
- 使用Thread 或handlerThread时,可提高线程优先级,加快执行时间
- 使用AsyncTask 处理短时的操作,由于AsyncTask 是串行执行的,高频的操作会造成阻塞。如果操作很频繁的任务或耗时较长的任务交给HandlerThread,支持手动管理操作流。如果高度并行且量级较大的任务,可以交给ThreadPoolExecutor,可有自动的管理线程的创建销毁,根据任务负载平衡,调整线程优先级。
OOM
原因
OOM全称为“Out of memory”,即内存溢出异常.
- 内存溢出 当前占用的内存+申请的内存 > Dalvik虚拟机的最大内存限制
- 内存抖动 对象频繁的创建和回收,区别于内存溢出。
- 内存泄漏 内存由于各种原因未释放,无法被GC回收,导致的资源浪费。积累的多了会造成OOM
优化
- 【选择合适的图片尺寸进行加载】,需要缩略图时不加载大图,ListView在滑动时不进行加载
- 【及时释放Bitmap内存】Bitmap是通过BitmapFactory创建,并且具体是通JNI实现的,所以有一部分内存的在Java会自动被GC,但是在C里面的内存,只能通过调用recycle()来释放。
- 【图片压缩】加载图片之前先用inSampleSize(缩放比例)属性,计算出一个合适的缩放比例,避免不必要的大图加载。
- 【inBitmap属性】inBitmaps属性会提高安卓系统对Bitmap分配与释放的执行效率。通过这个属性Bitmap解码器去尝试使用已经存在的内存区域,新解码的bitmap不会先申请内存,而是尝试使用上一张bitmap占用的内存区域。(及时有很多图片,也只会占用屏幕能展示的一张图片的内存大小)
- 【捕获异常】系统在读取Bitmap的时候内存容易出现OOM异常,所以在实例化bitmap的时候要捕获异常处理。
- 【ListView复用ConvertView,LRU缓存】ListView中大量重复的条目,要对ConvertView复用。如果加载图片,可以使用LRU机制缓存图片(最近最少使用)
- 【避免在onDraw()创建对象】如果在onDraw()频繁创建对象会导致内存突然上升,频繁GC,内存抖动,严重了会OOM
- 【慎重使用多进程】使用多进程会使得代码逻辑更加复杂,如果使用不当,它可能会导致显著增加内存。
其他优化
线程优化
尽量使用线程池,避免在程序中存在大量的Thread。线程池可以重用内部的线程,从而避免了现场的创建和销毁所带来的性能开销,同时线程池还能有效地控制线程池的最大并发数,避免大量的线程因互相抢占系统资源从而导致阻塞现象发生。
Service使用优化
- 查看service是否存活以及降低优先级:
假如一个service工作完成,但是来不及关掉或者kill掉,用户又看不见,所以这个service将会一直在后台运行,势必耗电。所以我们可以降低某些不常用service进程的优先级,在系统内存吃紧的情况下, 进程优先级低的service容易被系统kill掉。除此之外,可以利用监听系统广播来判断service状态是否存活,死亡即可手动kill掉。 - 用IntentService代替Service开发:
普通服务一旦启动之后,就会一直处于运行状态,必须调用stopService()或者stopSelf()方法才能让服务停止下来。为了简单的创建一个异步的、会自动挺值得服务,Android专门提供了一个IntentService类。IntentService在运行完毕后自动停止,减少耗电量。
应用瘦身
- 只是用一套资源,例如只使用720P的一套资源
- 在gradle使用minifyEnabled进行Proguard混淆的配置,可大大减小APP大小
- 在gradle使用shrinkResources去除无用资源,并配合Android Studio自带的 “Remove Unused Resources”小插件。
- 使用svg矢量图替代png图标,占用资源更少
- 删除无用的语言包,在gradle中配置 resConfigs "zh"
- 使用图片压缩网站压缩png Tinypng的官方网站:/
- .so库文件能删除不必要的就尽量少保留.so库文件
- 使用7zip压缩打包工具,建议开启7zip,注意白名单的配置,否则会导致有些资源找不到
- 清理三方库和冗余代码
- 支持插件化,酌情选择
写在最后
-
很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,对此我整理了一些资料,需要的可以免费分享给大家
领取方式:Android技术交流群653583088
-
很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,对此我整理了一些资料,需要的可以免费分享给大家
领取方式:Android技术交流群653583088
更多推荐
Android性能优化之异常处理应用瘦身
发布评论