UI组件在特定手机上会直播卡顿是什么原因因造成的

ZEALER 科技生活第一站
简单说明OS和UI(ROM)区别,以及手机卡顿问题
在此之前各位请先分清楚,什么是UI,什么是操作系统?1、目前市面上常见的操作系统只有三类:IOS系统,苹果家独占;windows mobile系统,微软家独占(部分厂商也推出);安卓系统,谷歌开发,除了上述两个之外最常见的就是了。当然,还有国内大名鼎鼎的阿里云OS,貌似只有魅族家再用。2、UI这部分重点说的是安卓。现在市面上出售的安卓手机,除了nexus系列之外,其余的都不是原生的安卓系统。而是经过厂商修改之后,形成具有自家特色的UI,或者简称ROM。包括360 OS、氢OS、锤子OS以及小米的MIUI等,都是在原生的安卓基础上修改而来的,并不是所谓的操作系统。3、安卓相比较IOS卡顿问题关于这点,我只能说这是手机厂商玩的把戏,使用的都是经过厂商修改的面目全非的安卓,而不是原生的那种安卓。现在安卓进化到7.0,已经完全不在卡顿,在2G内存的手机上面运行都不会有卡顿现象,甚至流畅度要比ios还要好。但是厂商为了区别于其他家的产品,在此基础上从系统底层修改了代码,是操作界面变得更加好看,更加讨好用户,也更加方便。然而这些修改,却在无形之中改变了安卓的样子。因为他们不是这款操作系统的开发者,他们只是相当于美化工作人员,但是却并未习得安卓系统的精髓所在,以至于原本流畅无比的系统,被这些厂商搞得卡顿无比,接着用户就开始抱怨安卓很卡,安卓垃圾bulabula……以此来引发一场论战。只能说,无形之中这些用户充当了厂家最好的,最廉价的宣传工具。而厂家呢,我就呵呵了。某厂商说“机器卡顿,那你就少安装 app”。我就呵呵呵了,老子买手机,你让我少装APP,我买你手机干个蛋啊?!!!4、硬件好的系统,需要搭配好的硬件才能体现其优势;好的硬件,也需要好的系统,才能发挥硬件的实力。就比如iphone4s,搭配ios9.0系统就会很卡顿,但是搭配当时与之相匹配的ios5.0系统就会很流畅;若是iphone6S搭配ios5,则无法完全发挥它的硬件功能。安卓手机也是如此,两三年前的手机升级到6.0.1系统,可能会觉得卡顿,但是当你换成最近两年的产品,并且是未经修改的原生安卓,你会发现其实也未必卡顿,并不是你想想的那么不堪。手机、电脑或者是游戏主机等,都是经过软件与硬件不断的优化磨合,才能达到最好的效果。写在结尾:在这里,真心想跟那些抱怨安卓,卡顿的用户们说一句:相同的硬件配置,卡顿原因真的不在你们啊,我也替你们感到难过。但是要是说拿着落后的硬件配置,想要获得旗舰级别的体验,您慢慢抱怨吧。下面配上我的两台机器截图:华为 nexus6P和iphone6.两台机器分别运行安卓7.0系统和ios10系统,都是原生未修改的。
点击查看所有点赞用户
打开微信,点击顶部的“发现”,使用 “扫一扫”即可将网页分享到我的朋友圈。
更多精彩内容推荐
需要才能回复手机后台到底是什么?真的会让手机变卡吗?
我的图书馆
手机后台到底是什么?真的会让手机变卡吗?
手机后台可以方便人们继续之前被打断的操作,但是太多手机后台又会造成手机卡顿,那么手机后台到底是怎么回事呢?其实很多人提到安卓的流畅度不如苹果其实是优化问题,本质上来说和后台程序没有什么关系。进程安卓的后台的设计本身就是淡化用户对后台的管理,由系统来完成系统资源的调配。Android系统会尽量维持一个进程的生命,直到最终需要为新的更重要的进程腾出内存空间。为了决定哪个该杀哪个该留,系统会跟据运行于进程内的组件的和组件的状态把进程置于不同的重要性等级。当需要系统资源时,重要性等级越低的先被淘汰。安卓的进程分6类:1.前台进程(foreground):目前正在屏幕上显示的进程和一些系统进程。最迟终止的就是前台程序。所谓前台程序其实就是你目前屏幕上运行着的程序,各种游戏、qq、微博……Android的应用在被切换到后台时,它其实已经被暂停了,并不会消耗cpu资源,只保留了运行状态.所以为什么有的程序切出去重进会到主界面.但是,一个程序如果想要在后台处理些东西,如音乐播放,它就会开启一个服务.服务可在后持续运行,所以在后台耗电的也只有带服务的应用了.这个在进程管理软件里能看到,标签是service.而你平时用home键调出来并且杀掉的,其实就是这个前台进程,但它其实是最无辜的,因为人家在后台也就占占你内存而已,并不造成耗电等问题,系统资源吃紧的时候,系统自己也会动手把他丫的杀了。2.可见进程(visible):一个进程不拥有运行于前台的组件,但是依然能影响用户所见。如,输入法。3.次要服务(secondaryserver):简单来说就是一些杀掉了不影响系统稳定运行,但是严重影响用户使用的服务。如gms、拨号器等,杀掉相当影响用户使用。4.后台进程(hidden):当前台程序 (foreground)被你一个home键打回大西洋的时候,它就进入后台进程的行列。wp、ios对待第三方应用的后台进程基本上都是墓碑模式,即进入后台即时冷藏;其实安卓4.0后也支持类似的操作,只是需要用户自行解决,同时冤魂不散的后台服务依旧在耗电耗内存污染通知栏。在系统内存不足找人开刀的时候,这种进程一般都是任人鱼肉的那种…5.空进程(empty):没有任何东西在内运行的进程,保留这类进程的唯一理由是高速缓存,这样可以提高下一次一个组件要运行它时的启动速度。系统经常为了平衡在进程高速缓存和底层的内核高速缓存之间的整体系统资源而杀死它们。(其实还有一种,叫内容供应节点,这货的存在就是给其他应用调用其内容的,我觉得这事是服务于应用,跟用户一级没什么直接联系,原来就没鸟它,现在补补咯……)以上5种,自上而下,越下重要性越低,系统需要资源的时候,死的也就最快。其实严格来说,安卓的后台程序是可以完全关闭的。因为根据如上的定义,后台进程(hidden)根本就是前台进程被打进冷宫,你长按home就能灭了它。而你所指的“不能彻底关掉”的,其实是程序在后台给你打开的服务、空进程。这些东西home键是关不掉的,需要用到一些特殊的应用。各个应用、手机助手杀“后台”的深度都不一样,有些只是杀到后台进程(hidden)一级,有些就杀到前台进程都不放过,最后连桌面都要重新加载…所以安卓其实是可以完全杀掉所有前台、后台、服务,但这样用着,不更蛋疼么?ios流畅本来其实是不关后台什么事的,但实际上ios运用墓碑模式,同时限制系统服务,所有推送都统一到一起。本身就极大地减少了内存的消耗;而wp更加是限制后台应用数量,以及只分配给每个应用一定量的内存,每个应用都只能运行在分配给它的内存中(计划经济…),所以wp理论上不会出现安卓那种内存溢出的情况。(其实安卓本身原来也有限制内存占用量,但这个量很小只有几十MB人家都是几百MB…当然了,鸡贼的开发者会用各种手段突破这个形同虚设的限制…)而安卓应用开多了,慢了,其实是内存占用太多,系统需要干掉几个没用的家伙,消耗了时间,而wp和ios因为其“计划经济”的优势,所以从来不需要临时挤内存。如果要牵扯到应用杀不死,或者说死了又咸鱼复活…这要说到android广播机制:系统接收到了一个动作、信息,比如系统接收到有人给你打电话,具有“广播接收器”的“电话”功能收到通知,就启动了,再执行给你响铃等等的动作。有些应用,它自己本身和“打电话”这个动作没什么关系,但是它也有属于“打电话”的那个类别的“广播接收器”,然后跟随广播被系统调用而启动。当一个程序放到后台时,系统可能将数据保存起来而让程序进行休眠,或者仅仅运行部分服务,仅仅当收到相关的申请时才恢复部分进程,处理完之后结束进程而保留服务——这些都是自动处理的,也就是说,如果用户运行的软件都是按照Android思想而设计的,那么除了明确有退出按键的一部分大型程序外,其他程序是都可以运行后扔到后台不用再管了的,当某个程序需要更多RAM时,系统会自动释放掉一些不重要且最近没有使用的程序;而当你打开某个曾经打开的程序时,系统会先检查RAM里是不是有这个程序的部分进程,然后进行恢复,这样可以更快打开它。举个最简单的例子:加入你的安卓手机安装了一些第三方的桌面插件,当你再运行一键杀后台进程的时候有很大的可能导致桌面程序被杀,结果手机顿时卡的无法正常运行甚至报错!当然了,如果智能手机本身RAM很小而且CPU不给力,系统自然会很频繁的终止进程释放内存,这就使得许多小内存的手机用起来感觉一卡一卡的了。于是很多论坛都开始讨论怎么样使得全杀过后空闲内存更大、怎样禁止自动启动某些进程——结果空闲RAM确实大了,用起来反而更卡了——随便切换个程序(如看书的时候来了个电话)系统都要重新启动几乎所有相关的进程,怎么能反应不迟钝。Android用RAM的方式,跟Windows、Windows Phone、Symbian是两回事。在Android里,RAM被用满了是件好事。它意味着你可以快速打开之前打开的软件,回到之前的位置。所以Android很有效的使用RAM,很多用户看到他们的RAM满了,就认为拖慢了他们的手机。而实际上,退出后重启这些程序才真正拖慢了手机的响应。而且这些自动杀进程的软件本身是个时刻活跃的进程,它始终在后台保持活跃使得CPU难以消停,反而增加了耗电量。但是对于很多国内软件,用完之后还是按一下退出吧,而对于规范化的程序,以及系统自带的那些程序(例如谷歌程序基本都没有退出),用过之后放后台就好。良好的手机使用习惯需要保持,就比如说不用的程序及时关掉,比如一些游戏程序,浏览器之类的在使用结束后完全是可以关闭的,这样既腾出了内存也会降低耗电量。几点建议1、安装的应用够用就好,如果你不是玩机发烧友,装几个必备的应用和一些自己需要的应用即可,无需安装过多的程序,否则会导致手机变慢,尤其是一些内存较小的机型。2、应用安装较多的时候,适当的进行删减,对于不常用,或是安装后觉得没用的软件要及时卸载,以免占用手机空间,影响手机的使用。3、养成按“返回键”或是程序自带的退出功能来退出应用的好习惯,如果不是为了要将程序切换至后台运行,就不要使用“房子键”退出,按“房子键”是将程序切至后台运行,并没有真正的退出,而按“返回键”或是通过软件的退出功能退出才是正在完全退出程序。4、使用任务管理功能,结束一些后台不用的程序或服务,来释放更多的内存,提高手机运行速度。5、如果您的手机硬件配置不是很好,可以适当的关闭手机中的一些窗口动画特效,来提高手机的运行和操作速度。6、定期清理手机中的缓存垃圾,释放更多的手机空间,换手机一个健康绿色的运行环境。7、如蓝牙,wifi,同步,GPS等这类的功能开关,如果不是经常使用,可以考虑关闭它们,用到时再开启,这样可以节约更多的电量,获取更多的待机时间。8、通过开机优化功能,查看一些开机启动项目,无需开机使用的应用就将其禁止,以免开机后消耗过多的资源。9、如果对手机不是特别了解,不要随意乱安装一些高级软件使用,如:需要root权限,或是可以修改系统功能的一些应用,此类程序可能会因为操作不当,出现一些未知问题。10、如果手机出现了未知问题,或是经过长时间使用导致系统缓慢不稳定,可以在设置──隐私设置中选择恢复出厂设置,来实现清空所有数据、恢复初始状态。注意,进行该操作前记得备份一下手机中的重要内容。这样是不是对你手机为什么会卡顿,以及手机后台多了一些了解呢?希望这些对你更好地使用你的手机有帮助。
TA的最新馆藏[转]&
喜欢该文的人也喜欢后使用快捷导航没有帐号?
平板/笔记本
云服务专区
手机用久了容易卡顿?只需五步,轻松解决,福利在最后!
1041213695
&独步江湖&
来自:浏览器
最新回复 6&天前
本帖最后由 我定不弃 于
13:14 编辑
00_meitu_2.jpg (21.47 KB, 下载次数: 38)
10:51 上传
  Android系统早已是全球最大的移动操作系统,用户已是千千万,不过在用户体验上离iphone还是有差距的,虽然Google一直努力的改善Android系统,卡顿问题却一直是大家的诟病,大家是否知道手机为何会卡顿?又有哪些方法可以减少手机卡顿呢?下面两张就分享搞机这么多年的经验,希望可以帮到大家!
卡顿的原因,基本上分为这几种
 安装的软件太多、手机系统不断升级,手机**太多 02 安卓手机后台应用自动重启占用RAM 03 手机使用太长时间没有关机 04 闪存读写性能不佳或者运行内存太小 05 老版本的手机没有开发GPU加速,只靠CPU合成画面 06 国内一些毒瘤软件开发水平太烂
↓↓↓那下面我们就对症下药↓↓↓
一、闪存安装包、卸载不常用软件
01.jpg (59.14 KB, 下载次数: 39)
10:52 上传
  是不是还有粉粉下载完应用之后,都不删除安装包的!(删除安装包对应用没有任何影响)这些文件就会一直存在你的手机存储里面,也会导致你的爱机慢慢变卡的,还有些小女生特别喜欢下载没用的APP,我身边就有这样的例子,难怪你的手机会卡!(下载应用最好去手机自带的应用市场)删除安装包:如果当时没能及时删除,可以进应用市场——管理——安装包管理中删除
二、优化加速、禁止后台自启
  我想说自带的手机管家是很强大的,而且第三方手机管家和手机系统会有冲突!
02.jpg (47.06 KB, 下载次数: 42)
10:52 上传
<font color="#.可进手机管家——优化加速——结束一些后台应用;
2.取消受保护的后台应用:设置——受保护的后台应用——去点一些受保护的应用;
三、减轻手机运行内存RAM
游客,如果您要查看本帖隐藏内容请
四、手机双清
  由于手机不断升级,导致手机中的系统**越来越多(次**只能用双清的办法来解决),双清的具体操作可见此教程:
五、终极方法——硬件提速
游客,如果您要查看本帖隐藏内容请
想要了解Mate S的小伙伴可以点击:
width:100%">
&略有小成&
来自:浏览器
感谢楼主分享
width:100%">
&炉火纯青&
来自:浏览器
width:100%">
&自成一派&
来自:浏览器
好帖子,学习下
width:100%">
&略有小成&
来自:浏览器
!!!!!!!
width:100%">
&炉火纯青&
来自:浏览器
多学习知识了
width:100%">
&登堂入室&
来自:浏览器
width:100%">
&独步江湖&
来自:浏览器
谢谢分享。。。。。
width:100%">
&登堂入室&
来自:浏览器
看看怎样的
width:100%">
&独步江湖&
来自:浏览器
????????
width:100%">
1 / 370 页
好基友勋章
花粉好机友,注册时间大于99天
1000万花粉
纪念花粉俱乐部注册花粉数超过1000万
申请成为热心花粉,满足热心花粉条件即可获得!http://cn./forum.php?mod=viewthread&tid=183642
近看城中景台风前的海上日出尝试P10水下摄影贵州黄果树景区田子坊随拍的乐趣钟情鼓浪屿
花粉客户端
Make it Possible
Make your device special
华为云服务
Huawei cloud services
音乐播放器
Huawei Music
Huawei Vmall
没有最新动态
关注花粉俱乐部
联系我们:
|关注花粉俱乐部:
Copyright (C)
华为软件技术有限公司 版权所有 保留一切权利Android开发(11)
转载请标明出处:
2015年初google发布了性能优化典范,发了16个小视频供大家欣赏,当时我也将其下载,通过微信公众号给大家推送了百度云的下载地址(地址在文末,ps:欢迎大家订阅公众号),那么近期google又在udacity上开了系列类的相关课程。有了上述的参考,那么本性能优化实战教程就有了坚实的基础,本系列将结合实例为大家展示如何去识别、诊断、解决Android应用开发中存在的性能问题。那么首先带来的就是大家最关注的渲染的性能优化(~~渲染就是把东西绘制到屏幕上)。
ps:本博客所有案例可能并不会完全按照Google给出的例子,因为范例代码比较多且不好在博客中展示,所以基本代码都会经过调整,但表达的意思不会变。
2、 Android渲染机制
大家自己编写App的时候,有时会感觉界面卡顿,尤其是自定义View的时候,大多数是因为布局的层次过多,存在不必要的绘制,或者onDraw等方法中过于耗时。那么究竟需要多快,才能给用户一个流畅的体验呢?那么就需要简单了解下Android的渲染机制,一图胜千言:
Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染,那么整个过程如果保证在16ms以内就能达到一个流畅的画面。那么如果操作超过了16ms就会发生下面的情况:
如果系统发生的VSYNC信号,而此时无法进行渲染,还在做别的操作,那么就会导致丢帧的现象,(大家在察觉到APP卡顿的时候,可以看看logcat控制太,会有drop frames类&#20284;的警告)。这样的话,绘制就会在下一个16ms的时候才进行绘制,即使只丢一帧,用户也会发现卡顿的~~(ps:上面标识不应该是32ms么,咋是34ms,难道我错过了什么)。
好了,很多朋友会不会奇怪为什么是16ms,16ms意味着着1000/60hz,相当于60fps,那么只要解释为什么是60fps,好在这个问题,网上有解答:
这是因为人&#30524;与大脑之间的协作无法感知超过60fps的画面更新。12fps大概类&#20284;手动快速翻动书籍的帧率,这明显是可以感知到不够顺滑的。24fps使得人&#30524;感知的是连续线性的运动,这其实是归功于运动模糊的
效果。24fps是电影胶圈通常使用的帧率,因为这个帧率已经足够支撑大部分电影画面需要表达的内容,同时能够最大的减少费用支出。但是低于30fps是
无法顺畅表现绚丽的画面内容的,此时就需要用到60fps来达到想要的效果,当然超过60fps是没有必要的(据说Dart能够带来120fps的体验)。本引用来源:
好了,有了对Android渲染机制基本的认识以后,那么我们的卡顿的原因就在于没有办法在16ms内完成该完成的操作,而主要因素是在于没有必要的layouts、invalidations、Overdraw。渲染的过程是由CPU与GPU协作完成,下面一张图很好的展示出了CPU和GPU的工作,以及潜在的问题,检测的工具和解决方案。
如果你对上图感到不理解,没关系,你只要知道问题:
通过Hierarchy Viewer去检测渲染效率,去除不必要的嵌套通过Show GPU Overdraw去检测Overdraw,最终可以通过移除不必要的背景以及使用canvas.clipRect解决大多数问题。
如果你还觉得不能理解,没关系,文本毕竟是枯燥的,那么结合实例来展示优化的过程。
3、Overdraw的检测
对于性能优化,那么首先肯定是去发现问题,那么对么overdraw这个问题,还是比较容易发现的。
按照以下步骤打开Show GPU Overrdraw的选项:
设置 -& 开发者选项 -& 调试GPU过度绘制 -& 显示GPU过度绘制
好了,打开以后呢,你会发现屏幕上有各种颜色,此时你可以切换到需要检测的程序,对于各个色块,对比一张Overdraw的参考图:
那么如果你发现你的app上深红色的色块比较多,那么可能就要注意了,接下来就开始说如果遇到overdraw的情况比较严重我们该则么处理。
4、Overdraw 的处理方案一:移除不必要的background
下面看一个简单的展示ListView的例子:
activity_main
&?xml version=&1.0& encoding=&utf-8&?&
xmlns:android=&/apk/res/android&
android:layout_width=&match_parent&
android:layout_height=&match_parent&
android:paddingLeft=&@dimen/activity_horizontal_margin&
android:paddingRight=&@dimen/activity_horizontal_margin&
android:background=&@android:color/white&
android:paddingTop=&@dimen/activity_vertical_margin&
android:paddingBottom=&@dimen/activity_vertical_margin&
android:orientation=&vertical&
android:layout_width=&match_parent&
android:layout_height=&wrap_content&
android:padding=&@dimen/narrow_space&
android:textSize=&@dimen/large_text_size&
android:layout_marginBottom=&@dimen/wide_space&
android:text=&@string/header_text&/&
android:id=&@+id/id_listview_chats&
android:layout_width=&match_parent&
android:background=&@android:color/white&
android:layout_height=&wrap_content&
android:divider=&@android:color/transparent&
android:dividerHeight=&@dimen/divider_height&/&
12345678910111213141516171819202122232425262728291234567891011121314151617181920212223242526272829
item的布局文件
&?xml version=&1.0& encoding=&utf-8&?&
xmlns:android=&/apk/res/android&
android:layout_width=&match_parent&
android:layout_height=&match_parent&
android:orientation=&horizontal&
android:paddingBottom=&@dimen/chat_padding_bottom&&
android:id=&@+id/id_chat_icon&
android:layout_width=&@dimen/avatar_dimen&
android:layout_height=&@dimen/avatar_dimen&
android:src=&@drawable/joanna&
android:layout_margin=&@dimen/avatar_layout_margin& /&
android:layout_width=&match_parent&
android:layout_height=&wrap_content&
android:background=&@android:color/darker_gray&
android:orientation=&vertical&&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:background=&@android:color/white&
android:textColor=&#78A&
android:orientation=&horizontal&&
xmlns:android=&/apk/res/android&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:layout_alignParentLeft=&true&
android:padding=&@dimen/narrow_space&
android:text=&@string/hello_world&
android:gravity=&bottom&
android:id=&@+id/id_chat_name& /&
xmlns:android=&/apk/res/android&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:layout_alignParentRight=&true&
android:textStyle=&italic&
android:text=&@string/hello_world&
android:padding=&@dimen/narrow_space&
android:id=&@+id/id_chat_date& /&
xmlns:android=&/apk/res/android&
android:layout_width=&match_parent&
android:layout_height=&match_parent&
android:padding=&@dimen/narrow_space&
android:background=&@android:color/white&
android:text=&@string/hello_world&
android:id=&@+id/id_chat_msg& /&
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
Activity的代码
package com.zhy.performance_01_
import android.os.B
import android.os.PersistableB
import android.support.annotation.N
import android.support.v7.app.AppCompatA
import android.view.LayoutI
import android.view.V
import android.view.ViewG
import android.widget.ArrayA
import android.widget.ImageV
import android.widget.ListV
import android.widget.TextV
* Created by zhy on 15/4/29.
public class OverDrawActivity01 extends AppCompatActivity
private ListView mListV
private LayoutInflater mI
protected void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_overdraw_01);
mInflater = LayoutInflater.from(this);
mListView = (ListView) findViewById(R.id.id_listview_chats);
mListView.setAdapter(new ArrayAdapter&Droid&(this, -1, Droid.generateDatas())
public View getView(int position, View convertView, ViewGroup parent)
ViewHolder holder = null ;
if(convertView == null)
convertView = mInflater.inflate(R.layout.chat_item,parent,false);
holder = new ViewHolder();
holder.icon = (ImageView) convertView.findViewById(R.id.id_chat_icon);
holder.name = (TextView) convertView.findViewById(R.id.id_chat_name);
holder.date = (TextView) convertView.findViewById(R.id.id_chat_date);
holder.msg = (TextView) convertView.findViewById(R.id.id_chat_msg);
convertView.setTag(holder);
holder = (ViewHolder) convertView.getTag();
Droid droid = getItem(position);
holder.icon.setBackgroundColor(0x44ff0000);
holder.icon.setImageResource(droid.imageId);
holder.date.setText(droid.date);
holder.msg.setText(droid.msg);
holder.name.setText(droid.name);
return convertV
class ViewHolder
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576771234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
实体的代码
package com.zhy.performance_01_
import java.util.ArrayL
import java.util.L
public class Droid
public int imageId;
public Droid(String msg, String date, int imageId, String name)
this.msg =
this.date =
this.imageId = imageId;
this.name =
public static List&Droid& generateDatas()
List&Droid& datas = new ArrayList&Droid&();
datas.add(new Droid(&Lorem ipsum dolor sit amet, orci nullam cra&, &3分钟前&, -1, &alex&));
datas.add(new Droid(&Omnis aptent magnis suspendisse ipsum, semper egestas&, &12分钟前&, R.drawable.joanna, &john&));
datas.add(new Droid(&eu nibh, rhoncus wisi posuere lacus, ad erat egestas&, &17分钟前&, -1, &7heaven&));
datas.add(new Droid(&eu nibh, rhoncus wisi posuere lacus, ad erat egestas&, &33分钟前&, R.drawable.shailen, &Lseven&));
123456789101112131415161718192021222324252627282930313233343536123456789101112131415161718192021222324252627282930313233343536
现在的效果是:
注意,我们的需求是整体是Activity是个白色的背景。
开启Show GPU Overdraw以后:
对比上面的参照图,可以发现一个简单的ListView展示Item,竟然很多地方被过度绘制了4X 。 那么,其实主要原因是由于该布局文件中存在很多不必要的背景,仔细看上述的布局文件,那么开始移除吧。
不必要的Background 1
我们主布局的文件已经是background为white了,那么可以移除ListView的白色背景
不必要的Background 2
Item布局中的LinearLayout的android:background=&@android:color/darker_gray&
不必要的Background 3
Item布局中的RelativeLayout的android:background=&@android:color/white&
不必要的Background 4
Item布局中id为id_msg的TextView的android:background=&@android:color/white&
这四个不必要的背景也比较好找,那么移除后的效果是:
对比之前的是不是好多了~~~接下来还存在一些不必要的背景,你还能找到吗?
不必要的Background 5
这个背景比较难发现,主要需要看Adapter的getView的代码,上述代码你会发现,首先为每个icon设置了背景色(主要是当没有icon图的时候去显示),然后又设置了一个头像。那么就造成了overdraw,有头像的完全没必要去绘制背景,所有修改代码:
Droid droid = getItem(position);
if(droid.imageId ==-1)
holder.icon.setBackgroundColor(0x4400ff00);
holder.icon.setImageResource(android.R.color.transparent);
holder.icon.setImageResource(droid.imageId);
holder.icon.setBackgroundResource(android.R.color.transparent);
12345678910111234567891011
ok,还有最后一个,这个也是非常容易被忽略的。
不必要的Background 6
记得我们之前说,我们的这个Activity要求背景色是白色,我们的确在layout中去设置了背景色白色,那么这里注意下,我们的Activity的布局最终会添加在DecorView中,这个View会中的背景是不是就没有必要了,所以我们希望调用mDecor.setWindowBackground(drawable);,那么可以在Activity调用getWindow().setBackgroundDrawable(null);。
setContentView(R.layout.activity_overdraw_01);
getWindow().setBackgroundDrawable(null);1212
ok,一个简单的listview显示item,我们一共找出了6个不必要的背景,现在再看最后的Show GPU Overdraw 与最初的比较。
ok,对比参照图,基本已经达到了最优的状态。
5、Overdraw 的处理方案二:clipRect的妙用
我们在自定义View的时候,经常会由于疏忽造成很多不必要的绘制,比如大家看下面这样的图:
多张卡片叠加,那么如果你是一张一张卡片从左到右的绘制,效果肯定没问题,但是叠加的区域肯定是过度绘制了。
并且material design对于界面设计的新的风&#26684;更容易造成上述的问题。那么有什么好的方法去改善呢?
答案是有的,android的Canvas对象给我们提供了很便利的方法clipRect就可以很好的去解决这类问题。
下面通过一个实例来展示,那么首先看一个效果图:
左边显示的时效果图,右边显示的是开启Show Override GPU之后的效果,可以看到,卡片叠加处明显的过度渲染了。(ps:我对这个View添加了一个背景色~~仔细看下面的代码)* View代码
package com.zhy.performance_01_
import android.content.C
import android.graphics.B
import android.graphics.BitmapF
import android.graphics.C
import android.view.V
* Created by zhy on 15/4/30.
public class CardView extends View
private Bitmap[] mCards = new Bitmap[3];
private int[] mImgId = new int[]{R.drawable.alex, R.drawable.chris, R.drawable.claire};
public CardView(Context context)
super(context);
Bitmap bm = null;
for (int i = 0; i & mCards. i++)
bm = BitmapFactory.decodeResource(getResources(), mImgId[i]);
mCards[i] = Bitmap.createScaledBitmap(bm, 400, 600, false);
setBackgroundColor(0xff00ff00);
protected void onDraw(Canvas canvas)
super.onDraw(canvas);
canvas.save();
canvas.translate(20, 120);
for (Bitmap bitmap : mCards)
canvas.translate(120, 0);
canvas.drawBitmap(bitmap, 0, 0, null);
canvas.restore();
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849501234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
Activity代码
* Created by zhy on 15/4/30.
public class OverDrawActivity02 extends AppCompatActivity
protected void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(new CardView(this));
}12345678910111213141234567891011121314
那么大家可以考虑下如何去优化,其实很明显哈,我们上面已经说了使用cliprect方法,那么我们目标直指
自定义View的onDraw方法。
修改后的代码:
protected void onDraw(Canvas canvas)
super.onDraw(canvas);
canvas.save();
canvas.translate(20, 120);
for (int i = 0; i & mCards. i++)
canvas.translate(120, 0);
canvas.save();
if (i & mCards.length - 1)
canvas.clipRect(0, 0, 120, mCards[i].getHeight());
canvas.drawBitmap(mCards[i], 0, 0, null);
canvas.restore();
canvas.restore();
}12345678910111213141516171819202122231234567891011121314151617181920212223
分析得出,除了最后一张需要完整的绘制,其他的都只需要绘制部分;所以我们在循环的时候,给i到n-1都添加了clipRect的代码。
最后的效果图:
可以看到,所有卡片变为了淡紫色,对比参照图,都是1X过度绘制,那么是因为我的View添加了一个
ff00ff00的背景,可以说明已经是最优了。
如果你按照上面的修改,会发现最终效果图不是淡紫色,而是青色(2X),那是为什么呢?因为你还忽略了
一个优化的地方,本View已经有了不透明的背景,完全可以移除Window的背景了,即在Activity中,添加getWindow().setBackgroundDrawable(null);代码。
好了,说完了Overdraw的检测与处理,那么还剩下一个layouts、invalidations过慢的问题,那么这类问题主要可能是你的XML层级过多导致的,当然也有很好的工具可以用来检测,那么就是Hierarchy Viewer。
6、减少不必要的层次:巧用Hierarchy Viewer
1、Hierarchy Viewer工具简介
Android SDK中包含这个工具,不过大家肯定也不陌生了~~~
那么就简单说一下它在哪,如何使用,以及真机无法使用该工具该怎么解决。
Hierarchy Viewer在哪?
本博客使用IDE为Android Studio,那么只需要按照下图步骤即可找到:
其他IDE的兄弟,找到这个肯定没问题,不过还是建议慢慢的转向AS。
如何使用?
一图胜千言:
关注下,所有框住的区域~~
无法连接真机调试怎么办?
如果你不存在这样的问题,直接跳过本节。
Android的官方文档中,有这么一句话:
出于安全考虑,Hierarchy Viewer只能连接Android开发版手机或是模拟器
看来的确是存在这样的问题了,并且网上也有一些解决方案,修改源码神马的,有兴趣去试试。
这里推荐一种解决方案:romainguy在github上有个项目,可以下载下来导入到IDE中,里面有个ViewServer的类,类注释上也标注了用法,在你希望调试的Activity以下该三个方法中,添加几行代码:
* public class MyActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ViewServer.get(this).addWindow(this);
public void onDestroy() {
super.onDestroy();
ViewServer.get(this).removeWindow(this);
public void onResume() {
super.onResume();
ViewServer.get(this).setFocusedWindow(this);
* &/pre&1234567891011121314151617181912345678910111213141516171819
记得先添加依赖,别问我怎么找不到ViewServer这个类,添加以上3行以后,手机运行至该Activity,重启下Android Device Moniter,然后就ok了,我就是这种方法调试的,哈~~
2、优化案例
好了,上面介绍完成了如何使用Hierarchy Viewer,下面使用一个案例来说明问题。
主要就是个布局文件:
&?xml version=&1.0& encoding=&utf-8&?&
xmlns:android=&/apk/res/android&
android:orientation=&vertical&
android:layout_width=&match_parent&
android:layout_height=&wrap_content&&
xmlns:android=&/apk/res/android&
android:orientation=&horizontal&
android:layout_width=&match_parent&
android:layout_height=&wrap_content&
android:layout_marginTop=&@dimen/activity_vertical_margin&&
android:id=&@+id/chat_author_avatar1&
android:layout_width=&@dimen/avatar_dimen&
android:layout_height=&@dimen/avatar_dimen&
android:layout_margin=&@dimen/avatar_layout_margin&
android:src=&@drawable/joanna&/&
android:layout_width=&match_parent&
android:layout_height=&wrap_content&
android:orientation=&vertical&&
android:layout_width=&match_parent&
android:layout_height=&wrap_content&
android:text=&@string/line1_text& /&
android:layout_width=&match_parent&
android:layout_height=&wrap_content&
android:text=&@string/line2_text&/&
xmlns:android=&/apk/res/android&
android:orientation=&horizontal&
android:layout_width=&match_parent&
android:layout_height=&wrap_content&
android:layout_marginTop=&@dimen/activity_vertical_margin&&
android:id=&@+id/chat_author_avatar2&
android:layout_width=&@dimen/avatar_dimen&
android:layout_height=&@dimen/avatar_dimen&
android:layout_margin=&@dimen/avatar_layout_margin&
android:src=&@drawable/joanna&/&
android:id=&@+id/rl_line1&
android:layout_width=&match_parent&
android:layout_height=&wrap_content&
android:layout_toRightOf=&@id/chat_author_avatar2&
android:text=&@string/line1_text& /&
android:id=&@+id/rl_line2&
android:layout_width=&match_parent&
android:layout_height=&wrap_content&
android:layout_below=&@id/rl_line1&
android:layout_toRightOf=&@id/chat_author_avatar2&
android:text=&@string/line2_text& /&
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970711234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
package com.zhy.performance_01_
import android.os.B
import android.support.v7.app.ActionBarA
import com.android.debug.hv.ViewS
public class CompareLayoutActivity extends ActionBarActivity
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_compare_layouts);
ViewServer.get(this).addWindow(this);
protected void onResume()
super.onResume();
ViewServer.get(this).setFocusedWindow(this);
protected void onDestroy()
super.onDestroy();
ViewServer.get(this).removeWindow(this);
12345678910111213141516171819202122232425262728293031323334351234567891011121314151617181920212223242526272829303132333435
可以看到我们的Activity里面添加了ViewServer相关的几行代码。
然后手机打开此Activity,打开Android Device Moniter,切换到Hierarchy Viewer视图,可以看到:
点击LinearLayout,然后点击Profile Node,你会发现所有的子View上面都有了3个圈圈,
(取色范围为红、黄、绿色),这三个圈圈分别代表measure 、layout、draw的速度,并且你也可以看到实际的运行的速度,如果你发现某个View上的圈是红色,那么说明这个View相对其他的View,该操作运行最慢,注意只是相对别的View,并不是说就一定很慢。
红色的指示能给你一个判断的依据,具体慢不慢还是需要你自己去判断的。
好了,上面的布局文件展示了ListView的Item的编写的两个版本,一个是Linearlayout嵌套的,一个是RelativeLayout的。上图也可以看出Linearlayout的版本相对RelativeLayout的版本要慢很多(请多次点击Profile Node取样)。即可说明RelativeLayout的版本更优于RelativeLayout的写法,并且Hierarchy Viewer可以帮助我们发现类&#20284;的问题。
恩,对了,第一个例子里面的ListView的Item的写法就是Liearlayout嵌套的,大家有兴趣可以修改为RelativeLayout的写法的~~~
到此我们就介绍完成了如何去对Android渲染进行优化,如果你的app有卡顿的情况,可以通过使用上述的工具首先去检测收集数据,然后按照上面提供的方法进行优化~~have a nice day ~~
群号:,欢迎入群
微信公众号:hongyangAndroid
(欢迎关注,第一时间推送博文信息)
(密码:3h9v)
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:2430次
排名:千里之外
原创:14篇

我要回帖

更多关于 玩lol卡顿是什么原因 的文章

 

随机推荐