Android性能优化---内存优化

读书笔记:Android应用性能优化最佳实践

一、影响卡顿的基本原因

1.绘制任务太重
2.主线程任务耗时太长

二、页面绘制的流程

CPU准备数据---GPU从缓存列表获取数据----Display显示数据

三、性能优化检测工具

1.Profile GPU rendering :GPU呈现模式分析

或是使用dumpsys命令更直观的查看绘制的耗时
adb shell dumpsys gfxinfo com.efrobot.robot.video

2.Systrace UI
分析UI的性能
参考Systrace
3.TraceView
分析函数的执行过程和耗时时间
参考TraceView
4.Hierarchy Viewer
查看Layout的嵌套以及绘制的时间
5.Java Heap
查看内存分配
6.Allocation Trace
观察一段时间内,内存分配的次数和类
7.Show GPU Overdraw
手机检查过渡绘制

四、布局优化

1.减少层级
合理的使用布局

RelativeLayout:绘制层级少,可以替代LinearLayout多嵌套才能实现的效果,但是性能差,因为要横向,纵向测量两次。
LinearLayout:测量少,但是实现复杂布局需要多次嵌套。

使用Merge标签减少布局,优化布局层级

1.在Activity整体的布局中,跟布局元素要是FrameLayout
2.必须为该布局指定一个ViewGroup,并且attachToRoot为true
3.不能在ViewStub中使用

使用ViewStub提高显示速度:当布局在加载时不是所有所有元素都要显示时,可以使用

ViewStub只能加载布局
加载一次后就不能再对布局做操作

避免默认主题的背景:使用activity的自动主题时会有一个默认背景,由DecorView持有

this.getWindow().setBackground(null)

五、启动耗时优化

1.获取activity的启动时间
使用ADB命令

adb shell am start -W [packageName]/packageName.ActivityName

2.代码打点

Application,Activity声明周期打点
数据库操作打点
其他的耗时业务打点
3.优化的方向
1.UI布局:检查是否过渡绘制,布局嵌套,掉帧严重
2.逻辑优化:异步加载,延期加载,分布加载
3.避免后台线程操作造成频繁的GC:例如在ListView滑动时禁止使用后台线程下载图片
4.使用TraceView查看updateDisplayListIfDirty方法,最后画面刷新到屏幕上需要调用DisplayList方法

六、动画优化

1.使用属性动画优化刷新率,尽量避免补间动画
2.在动画上使用硬件加速(慎重使用 )

七、内存优化

GC的过程中,任何工作线程都将停止,GC的时间越长,卡顿越明显,还会造成OOM问题。
1.对象的几个阶段:创建---使用---不可达---不可见--不可达---收集---回收
不可见:无法找到引用该对象的引用关系,但可能被静态变量,JNI层强引用,无法回收

2.内存分配
ART和Dalvik虚拟机在内存分配
LinearAlloc:存储虚拟机中的类以及永久数据,一块只读的空间
Zygote Space:
Allocation Space:分配内存区域
Image Space:负责分配预加载类
Large Space:负责分配大对象地址

3.内存回收机制
年轻区---老年区--持久区

新生对象首先在eden区创建,当eden区满时,会将存活的内存放到s0区,s0区满时,会将此时还活着的对象移动到s1区域s0清零,当s1区域也满时,会复制s1中的数据到s0,反复执行几次后仍然活着的对象会放到老年代。在老年代经理过几次gc仍然存活的对象会被移动到 持久区中。

4.使用Allocation Tracker查看内存分配
Allocation Tracker可以查看一段时间内内存分配的次数,和分配的大小,详见参考文章
https://blog.csdn.net/itfootball/article/details/48735041
https://blog.csdn.net/itfootball/article/details/48750849

5.分析Hprof文件
通过AndroidStudio生成Hprof文件,观察视图,使用Merge Shortest Path to GC roots,查看合并节点后,是否还有可达到该对象的路径,如果有那么表示该对象无法回收,可能出现内存泄漏

八、引用区分

1.强引用:不会被GC回收,回收不了会OOM
2.软引用:在虚拟机报告内存溢出前,如果内存不足回收对象
3.弱引用:GC就回收

九、内存优化

1.在1000数量级以内使用ArrayMap
2.使用基本类型加@IntDef和@StringDef类代替枚举
3.使用LruCache管理图片
4.图片内存优化

在android上加载图片,需要将图片加载成位图(由多个像素点组成的图),再解锁成位图后,内存=宽x高x单位内像素。图片被处理32bit/像素的位图(ARGB_8888),红,绿,蓝,透明各占8bit。即使图片不存在透明区也会分配8bit的透明区。

5.可以修改图片的格式
RGB_565(16bit),ARGB_4444(16bit),ALPHA_8(8bit)。小屏手机且对图像要求不高可以使用rgb,圆角头像可以使用ARGB4444,.

BitmapFactory.Options option =new BitmapFactory.Options()
options.inPreferredConfig=Bitmap.Config.RGB_565
BitmapFactory.decodeStream(is,null,options)

6.inSampleSize,inDensity,inTargetDensity:
如果图片在内存中的大小远远大于使用大小可以使用inSampleSize来压缩图片,inScaled 会按照现有密度重新划分目标密度,重新计算图片大小.

使用inSampleSize压缩图片,
BitmapFactory.Options option =new BitmapFactory.Options()
option.inJustDecodeBounds=true;
BitmapFactory.decodeStream(is,null,options)
options.inScaled=true;
options.inDensity=options.outWidth;0
options.inSampleSize=40
options.inTargetDensity=dstWidth*options.inSampleSize;
options.inJustDecode=false;

6.使用三级缓存对大量图片进行优化

内存--本地--网络

1.使用LruCache
将最近使用过对象的强引用放到LinkedHashMap中,将最近最少使用的对象移除。
2.内存复用
使用Bitmap的options对象的inBitmap参数:在LruCache移除图片后,可以将移除的图片加入到复用集合中,当需要加载新的图片时,先查找内存,再查找复用集合中是否有符合的图片。

Bitmap inBitmap=cache.getBitmapFromReusableSet()
if(inBitmap!=null){
  options.inBitmap=inBitmap;
}

3.使用磁盘缓存
使用DiskLruCache

十、String的优化

参考:http://www.androidchina.net/5940.html
String的值是存储在常量池(在编译时期将值保存在.class文件中)中的,一旦创建将不可以修改。

十一、存储优化

1.SharePreference优化
Editor的commit是同步写入,apply是异步写入。在不需要返回值的情况下,使用apply能够极大的提升性能
SharePreference的的put和getEditor()会锁定Editor对象,所以大量写入SharePreference对象最后提前获得一个Editor对象,并且通过标志位判断是否需要读写。

if(开关没有改变&&没有发生变化){
}

2.数据库优化
1.使用SQLiteStatement来执行插入操作

SQLiteStatement statement=getSqliteDB().compileStatement(STR_INSERT_STATEMENT_CONTACTS);
statement.clearBindings();
statement.bind..();

2.更好的方法是使用事物
在数据库插入代码中,如果没有显示的使用事物,系统会自动创建一个事物,如果插入的频繁就会频繁的创建事物。所以显示的创建一次事物,可以提高效率。

getSqliteDB().beginTranscation();
for(){
   getSqliteDB().insert(...)
}
getSqliteDB().setTranscationSuccessful();
getSqliteDB().endTranscation();

十二、Service的包活

1.守护进程
2.网络连接保持和Service的交互
3.使用SyncAdapter:是一个系统服务,通过系统的定时器更新数据到ContentProvider,工作在一个独立的进程,属于核心进程级别。使用它本身也会提高进程级别

十三、耗电优化

1.android5.0提供了Battery Historian查看电量使用
2.使用命令

//获取电量权限,并重置电量日志
adb shell dumpsys batterystats --enable full-wake-history
shell dumpsys batterystats --reset
//保存数据
adb bugreport >bugreport.txt

将文件转化为html,需要下载battery-historian

python historian.py -a bugreport.txt >battery.html

3.注意消耗:使用WakeLock一定要记得释放
4.使用JobScheduler执行部分任务

重要不紧急的任务
耗电量较大的任务
可以批量执行的任务

十二、代码审查

1.单一职责,一个模块只负责一件事
2.对象的可扩展开放,可修改关闭
3.代码复用要提取一个公共类
4.是否有更好的实现
5.错误是否被更好的处理,而不是粗略屏蔽
6.效率:选用的算法是否更有效率

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

推荐阅读更多精彩内容