性能优化点

https://testerhome.com/topics/4304

一、选择适当的基类和控件

a、选择合适的基类

我们在继承基类时,可能基类中做了很多事情但子类中并不会用到,反而对性能有影响

例子1: Setting的某子页面为了使用SettingsPreferenceFragment中的某一两个方法而继承了SettingsPreferenceFragment,而其他大多数变量和方法并没有使用到,如:在SettingsPreferenceFragment在onCreateView中inflate的布局但在该子类中并不会用到,而且findViewById实例化的变量也用不上.

优化方法:继承普通的Fragment,将用到SettingsPreferenceFragment中的1,2个方法提取出来使用即可.

例子2: Setting主界面LeUIMainSettings的父类是SettingsActivity,在SettingsActivity的 onCreate()函数中调用setContentView(),而在子类的onCreate方法中又重新调用setContentView()设置了不同的view,导致引起无效的inflate布局

优化方法:该情况下由于子类很多地方都对父类有着依赖,必须继承该父类,但我们可以做到:如果子类需要设置不同于父类的layout布局时:添加标志位,在父类调用setContentView()前进行判断,避免无效设置.

b、选择合适的控件

为了使用控件的某一简单的功能引入了三方控件,但该控件中可能进行许多复杂的操作并不会用上.

例子:在setting中系统设置页面listview使用的是PinnedHeaderListView控件,而跟踪代码发现并没有利用到PinnedHeaderListView的特性,反而PinnedHeaderListView在onScroll方法中做了许多判断逻辑和measure操作,导致初始加载和滚动listview时的耗时和丢帧.

优化方法:分析确定没有使用PinnedHeaderListView的必要性后改用原生的listView控件.

适当选择使用preference,preference的使用场景一般是:数据项条目数较为固定,展示比较简单,不会经常刷新的地方,而且当preference为自定义样式的preference时,PreferenceGroupAdapter并不会进行复用,导致每次

更新该条目时都会重新inflate.

例子:在Setting的应用设置页面采用的就是preference(自定义的preference),而该页面的数据会存在几次异步刷新,所以导致多次inflate所有条目,出现丢帧现象.

优化方法:改用listView,编写viewHolder,然后当数据变化后使用NotifyDataSetChange

二、延迟加载策略:

在尽量减少对内容展示的影响的情况下,延迟加载策略能有效的提高页面的进入速度

1.延迟ViewPager缓存页面:在使用ViewPager时,viewPager会自动帮我们缓存加载页面,因此我们在显示page1的时候page2也紧接着创建了.

例子:Setting主界面的主布局就是一个viewPager,左边是系统设置,右边是应用设置.用户最先看到是系统设置页面,因此我们可以让应用设置页面延迟加载以加快主界面进入速度.

优化方法:在应用设置页面采用handler发送一个delay 200ms的message再进行数据获取和列表刷新,这样既加快了启动速度,且当用户点击应用设置时也并感觉不到200ms的延迟.

2.当一个页面需要展示多项内容时,可以将必要和用户常用的内容模块第一时间展示,对于加载缓慢并不是急迫展示的内容延迟加载.

例子:Setting的电池子页面中,加载各App的耗电列表较为耗时,而且该部分模块处于页面较底部位置.

优化方法:将电池页面中的:电池总览和温度之类的信息在主线程同步加载显示,把各App的耗电加载放到子线程中计算之后再异步更新UI界面.

三、listView的优化

App性能优化,有很大一部分的优化都是在对ListView的展现和加载以及滑动卡顿进行优化,对于ListView优化除了使用viewHolder基础的优化,以下还例举了4点优化方向

1.通过性能工具分析发现:listView在obtainview中的inflate布局时耗时较长

例子:设置的系统设置页面使用的ListView就是在其Adapter的执行到getView时才进行view的inflate,因此会占用了一长段主线程的时间.

优化方法:子线程提前进行listview item view的inflate,并存储在内存变量中,在真正到listview的getview的时候可以直接使用内存变量中已经实例化好的View对象.

2.将getView中的耗时操作放到子线程中加载

例子:设置的系统设置页面的listView的每个item中都会展示相应图标,在每次getView时再进行图标的加载会比较耗时.

优化方法:在子线程中将图标先建好缓存,这样在getView显示图标时,可以直接拿来使用,并且有了缓存后不用每次getView的时候都重新加载.

3.简化ListView中item的布局

例子:设置的系统设置页面的listView的item中存在许多累赘的嵌套布局

优化方法:减少累赘布局层次,减轻inflate的工作.

4.ListView处于idle状态再进行更新,减少滑动过程中的丢帧现象

优化方法:通过监听listView的onScroll,我们可以知道当前listView的滚动状态,当判断到listView处于idle状态时我们再在getview中进行某些耗时的操作

例子:见: 六、避免频繁向主线程发送handler message

四、注意内存的使用,减少gc

1.选择变量实例化适当的位置,减少GC次数

例子:Setting中有些成员变量的实例化放到了onResume中,致使申请内存的次数增多,gc次数增加.

优化方法:将成员变量的实例化放到onCreate中.

2.避免每次重新构造listview的list数据

例子:在设置的系统设置页面中,每次跟新listView时,都是重新构造一份新的list数据,然后再更具相应逻辑remove掉一些条目.

优化方法:加载一份原始数据,更新时在copy一份对原始数据的引用,然后在copy后的List数据上进行条目的刷选.

五、合理使用同步锁

1.对于不同的临界区域或临界变量选择合适的锁

例子:LeuiApplicationsState类中所有的临界区域和临界变量所有地方使用了同一把锁,导致调用时出现很多等锁耗时的情况.

优化方法:分析代码逻辑对于不属于同一临界区域的代码和变量在不存在并发访问的问题的前提下,使用不同的同步锁.

2.避免出现主线程调用时,长时间等待子线程的锁资源.

例子1:在主线程调用LeuiApplicationsState中的某些方法时,会出现长时间等待LeuiApplicationsState中子线程中持有的锁资源.

优化方法:最好是能避免竞争同一把锁资源,如果必须使用同一把锁,可以调整调用先后顺序,减少同一时间内竞争同一把锁的情况.

例子2:在listView的优化过程中(子线程中提前inflate view),子线程中使用getSystemService的layoutInflate进行inflate,出现主线程等锁情况(因为:子线程中通过getSystemService获取到的layoutInflate是同一对象,而在inflate()函数中一开始就调用synchronized(mConstructorArgs))

优化方法:子线程中通过new一个新的PhoneLayoutInflate对象,避免出现与主线程竞争同一把锁的情况.

六、避免频繁向主线程发送handler message

避免频繁向主线程发送handler message,以阻塞主线程looper的message queue造成点击,滑动等事件不能得到及时处理,出现卡顿丢帧现象.

例子:设置应用管理中使用了工具类LeuiApplicationsState后台线程加载每个应用的图标和计算占用的空间大小,每加载出一个就发送handler消息到主线程中去,造成一开始滚动listView时卡顿丢帧

优化方法:消息通知在后台线程中回调或者将消息发送到子线程的looper中,然后当图标和空间大小加载一定数量后,并且判断listview处于idle状态后再抛给主线程处理.

七、其他

1.梳理业务逻辑去掉不用了的代码

在优化设置的过程中发现:一些耗时的代码的调用但并没有起到任何作用,确认后发现该部分代码是之前功能的遗留.

2.overDraw的优化:Overdraw概要

减少不必要的background层级,和减少layout布局中的嵌套层级

3.内存泄露的优化:检测内存泄露

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

推荐阅读更多精彩内容