PRO玩游戏帧数高但是卡顿模式,经常性的丢帧卡顿怎么办

5260人阅读
Android性能优化(13)
性能优化系列阅读
什么是卡顿及卡顿的衡量标准
产生卡顿的原因
通用优化流程
定位卡顿原因
什么是卡顿
卡顿是人的一种视觉感受,比如我们滑动界面时,如果滑动不流程我们就会有卡顿的感觉,这种感觉我们需要有一个量化指标,在编程时如果开发的程序超过了这个指标我们认为其是卡顿的。
FPS(帧率):每秒显示帧数(Frames per Second)。表示图形处理器每秒钟能够更新的次数。高的帧率可以得到更流畅、更逼真的动画。一般来说12fps大概类似手动快速翻动书籍的帧率,这明显是可以感知到不够顺滑的。30fps就是可以接受的,但是无法顺畅表现绚丽的画面内容。提升至60fps则可以明显提升交互感和逼真感,但是一般来说超过75fps就不容易察觉到有明显的流畅度提升了,如果是VR设备需要高于75fps,才可能消除眩晕的感觉。
开发app的性能目标就是保持60fps,这意味着每一帧你只有16ms≈1000/60的时间来处理所有的任务。Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染,如果每次渲染都成功,这样就能够达到流畅的画面所需要的60fps。
如果你的某个操作花费时间是24ms,系统在得到VSYNC信号的时候就无法进行正常渲染,这样就发生了丢帧现象。那么用户在32ms内看到的会是同一帧画面。
如果此时用户在看动画的执行或者滚动屏幕(如RecyclerView),就会感觉到界面不流畅了(卡了一下)。丢帧导致卡顿产生。
流畅的情况下:
出现了丢帧现象(卡顿)
严重丢帧(卡死了)
给我们一种感觉,如果帧率越低,卡顿就越严重,那么是不是就可以使用帧率来衡量卡顿那?
如何衡量卡顿
FPS的高低不能准确的反映应用的流程度。如下图所示,只有有更新的时候才刷新界面。
当界面没有变动的时候,手机不需要对界面进行更新,所以此时的FPS会很低,如果1秒钟内都没有变动那么FPS=0。所以我们需要利用其他方式来衡量应用的流程度,比如可以利用丢帧数来衡量。
单位时间内丢帧数可以反映出应用是否流程。不丢帧是终极目标,但每秒丢帧在6-7帧左右可以接受,如果丢10帧以上就需要优化了。
丢帧情况(单位时间内均匀分布)
对于我们开发人员来说,会使用一些工具找出卡顿比较集中的地方,找出原因,消除或减弱卡顿。(测试团队会有专门的工具去测试丢帧的情况)
卡顿产生的原因
核心:分析在16ms中我们的应用做了什么工作,那些工作阻止我们在16ms时更新界面。
通常情况下,在16ms中我们有那些工作需要处理。
单以XML布局被绘制出来为例进行说明。
处理过程:
CPU负责把UI组件计算成多边形和纹理
OpenGL负责绘制图像(Display List)
GPU栅格化需要显示内容并渲染到屏幕上
而实际开发中我们还加入交互、业务处理等工作,这些工作都需要在16ms中处理完成。对于开发人员来说,需要有一个工具,很直观的帮助我们判断出那些工作占用了多少时间。
Profile GPU Rendering
通过手机开发者选项中提供的Profile GPU Rendering(GPU呈现模式分析)功能,我们可以清楚的看到处理流程中各部分的耗时。手机端工具(开发助手àGPU渲染图)。建议大家在Android6.0及以上手机测试。
打开Profile GPU Rendering操作截图如下:
大家可以拿着真机配置一下。看看有什么变化。
条形图说明
水平方向的一根绿线代表16ms。
每条都代表一帧画面所有工作内容
每条中不同的颜色代表不同的工作内容
Android6.0及以上的手机颜色对应关系如下:
通用优化流程
第一步:UI层优化
1、UI问题比较容易查找
2、一旦出现问题影响范围广(xml、mesure、layout、draw、Display List 、栅格化……)
工具:设备过渡绘制查看功能、HierarchyViewer等
常见问题:过渡绘制、布局复杂、层级过深……
在屏幕一个像素上绘制多次(超过两次)。如:文本框,如果设置了背景颜色(黑色),那么显示的文字(白色)就需要在背景之上再次绘制。
打开手机开发者中的过渡绘制区域即可查看。蓝色标识这个区域绘制了两次。
如果大面积都是蓝色,属于正常情况。
重点关注大面积绿色及以后的,表示存在过渡绘制。
设备中的该选项只能直观的让我们感受到应用的界面是否存在过渡绘制,如果存在,我们需要利用Hierarchy Viewer查找布局中不合理的地方。
过渡绘制小案例
效果图如下
大面积存在过渡绘制,文字区域最严重。查询Item布局文件找出过渡绘制的原因
自定义控件绘制优化
Clip Rect 与 Quick Reject
Clip Rect:识别可见区域
Quick Reject:控件所在的矩形区域是否有交集
在Canvas中有上述两个方法,帮助我们进行判断,避免出现过渡绘制。
我们可以通过来帮助系统识别那些可见的区域,在这个区域之外的我们不在进行绘制。如侧拉菜单,当菜单显示的时候被菜单遮挡的部分是不用进行绘制的,一旦绘制就会出现过渡绘制现象。系统的控件会控制过渡绘制,但我们自己的控件就需要自行管理了。所以在使用侧拉菜单时就需要优先考虑系统提供的了。
如果系统没有提供的,我们自己编写时也需要注意,避免出现过渡绘制。
自定义控件过渡绘制
编写自定义控件MyVIew,在布局中引入该控件
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"&
图片资源数组
private int[] ids = new int[]{R.drawable.img1, R.drawable.img2, R.drawable.img3, R.drawable.img4, R.drawable.img5, R.drawable.img6};
初始化时加载图片资源,同时对一会需要使用到的画笔做初始化
private void init() {
for (int i = 0; i & 6; i++) {
imgs[i] = BitmapFactory.decodeResource(getResources(), ids[i]);
paint=new Paint();
paint.setAntiAlias(true);
先将图片摆放好
for (int i = 0; i & imgs. i++) {
canvas.drawBitmap(imgs[i],i*20,0,paint);
通过过渡绘制的开启,观察结果
原因比较简单,对于“大王”这张牌来说,我们不需要绘制完整的图片,如果都绘制了就会出现上面的情况
处理思路:找出牌需要绘制的区域,让canvas在绘制这张牌时仅仅按区域绘制一部分即可。对于“大王”这张牌来说我们仅仅绘制如下内容
重点来了,我们该如何划定这个区域? 在Canvas中clipRect方法可以帮助我们划定一个区域,进行绘制。
方法参数说明:
clipRect(int left, int top, int right, int bottom)
canvas.clipRect(0, 0, 20, imgs[i].getHeight());
设置完成后,我们来绘制大王这张牌。
canvas.drawBitmap(imgs[0],0,0,paint);
再增加循环,快速绘制所有的牌。
for (int i = 0; i & imgs. i++) {
canvas.clipRect(i * 20, 0, (i + 1) * 20, imgs[i].getHeight());
canvas.drawBitmap(imgs[i],i*20,0,paint);
大家会发现绘制完成的结果不是我们想要的。
我们需要借助save和restore来完成裁剪的操作。
save:用来保存Canvas的状态。save之后,可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作。
restore:用来恢复Canvas之前保存的状态。防止save后对Canvas执行的操作对后续的绘制有影响。
save和restore要配对使用(restore可以比save少,但不能多),如果restore调用次数比save多,会引发Error。save和restore之间,往往夹杂的是对Canvas的特殊操作
代码修改如下
for (int i = 0; i & imgs. i++) {
canvas.save();
canvas.clipRect(i * 20, 0, (i + 1) * 20, imgs[i].getHeight());
canvas.drawBitmap(imgs[i],i*20,0,paint);
canvas.restore();
剩下最后一个工作,把最上面的牌绘制完整
for (int i = 0; i & imgs. i++) {
canvas.save();
if(i&imgs.length-1) {
canvas.clipRect(i * 20, 0, (i + 1) * 20, imgs[i].getHeight());
}else if(i==imgs.length-1){
canvas.clipRect(i * 20, 0, i * 20+imgs[i].getWidth(), imgs[i].getHeight());
canvas.drawBitmap(imgs[i],i*20,0,paint);
canvas.restore();
Hierarchy Viewer(层级查看器)工具使用
Hierarchy Viewer可以很直接的呈现布局的层次关系,视图组件的各种属性。我们可以通过红,黄,绿三种不同的颜色来区分布局的Measure,Layout,Executive的相对性能表现如何。
选择需要查看的内容
查看各个节点Measure,Layout,Executive
三个小圆点, 依次表示Measure, Layout,Draw, 可以理解为对应View的onMeasure, onLayout, onDraw三个方法
绿色:表示该View的此项性能比该View Tree中超过50%的View都要快
黄色:表示该View的此项性能比该View Tree中超过50%的View都要慢
红色:表示该View的此项性能是View Tree中最慢的
Measure红点, 可能是布局中嵌套RelativeLayout, 或是嵌套LinearLayout都使用了weight属性.
Layout红点, 可能是布局层级太深
Draw红点, 可能是自定义View的绘制有问题, 复杂计算等
我们之前的小案例,可以进行层级优化
没有用的父布局——没有背景绘制或没有大小限制的父布局,不会对界面效果产生任何影响。特别是进来的布局,很容易产生问题。可以通过标签替代。
在布局层次一样的情况下,建议使用LinearLayout代替RelativeLayout。
使用LinearLayout导致的层次变深,可以使用RelativeLayout进行替换。同样的界面我们可以使用不同的方式去实现,选择一个层级最少的方案。
不常用的UI被设置成了GONE,尝试使用代替。
去掉多余的背景颜色,减少过渡绘制,对于有多层背景色的布局来说,留最上面的一层即可。谨慎使用alpha,如果后渲染的元素有设置alpha值,那么这个元素就会和屏幕上已经渲染好的元素做blend处理,这样会导致不少性能问题,特别是出现在列表的Item中。
对于使用Selector当背景的布局,可以将normal状态的color设置为透明。
我们不能因为提高性能而忽略了界面需要达到的效果(平衡Design与Performance)
第二步:代码问题查找
工具:Lint
常见问题:我们重点关注Performance和Xml中的一些建议
在绘制时实例化对象(onDraw)
手机不能进入休眠状态(Wake lock)
资源忘记回收
Handler使用不当倒置内存泄漏
没有使用SparseArray代替HashMap
未被使用的资源
布局中无用的参数
可优化布局(如:ImageView与TextView的组合是否可以使用TextView独立完成)
效率低下的 无用的命名空间等
Lint工具使用
Android Studio中开启Lint工具
选中需要分析的Module,点击工具栏中Analyze中的Inspect Code选项。
选择需要分析的Module或整个项目
我们可以逐一阅读一下,但是重点关注性能问题,xml中的一些问题也尽可能进行修复。
1、案例中性能问题处理
其他的一些性能问题
建议使用concate方法进行连接字符串,会比append的方式性能好。
2、案例中xml提到的内容如下
其他问题:
无效的命名空间
无效的布局参数
比如在线性布局中的控件使用到了相对布局中的属性,运行时需要处理,影响代码的执行效率。
3、案例中关于定义声明变量的警告
意见或建议
不断关注Lint中提到的问题,将公司中命名规范中没有提到的内容逐一补全。
Lint不是万能的。
第三步:优化App的逻辑层
工具:Traceview
常见问题:主线程耗时大的函数、滑动过程中的CPU工作问题,工具可以提供每个函数的耗时和调用次数,我们重点关注两种类型的函数:
主线程里占用CUP时间很长的函数,特别关注IO操作(文件IO、网络IO、数据库操作等)
主线程调用次数多的函数
使用Traceview找出卡住主线程的地方
Traceview工具使用
通过Android Studio打开里面的Android Device Monitor,切换到DDMS窗口,点击左边栏上面想要跟踪的进程,再点击上面的Start Method Profiling的按钮,如下图所示:
启动跟踪之后,再操控app,做一些你想要跟踪的事件,例如滑动RecyclerView,点击某些视图进入另外一个页面等等。操作完之后,回到Android Device Monitor,再次点击相同的按钮停止跟踪。此时工具会为刚才的操作生成TraceView的详细视图。
重点关注Incl Cpu Time、Call+Recur Calls/Total、Real Time/Call
通过降序排序,我们可以分别找到这两列中数值比较大的内容。
Incl(Inclusive) Cpu Time
方法本身和其调用的所有子方法占用CPU时间
Excl(Exclusive) Cpu Time
方法本身占用CPU时间
Incl Real Time
方法(包含子方法)开始到结束用时
Excl Real Time
方法本身开始到结束用时
Call + Recursion Calls/Total
方法被调用次数 + 方法被递归调用次数
Cpu Time/Call
方法调用一次占用CPU时间. 方法实际执行时间(不包括io等待时间)
Real Time/Call
方法调用一次实际执行时间. 方法开始结束时间差(包括等待时间)
我们可以在ViewHolder的设置数据中做点手脚,比如睡几毫秒(8ms),通过监控滚动,我们是否可以定位到问题代码。
不要阻塞UI线程,占用CUP较多的工作尽可能放在子线程中执行。
需要结合使用场景选择不同的线程处理方案
AsyncTask:为UI线程与工作线程之间进行快速的切换提供一种简单便捷的机制。适用于当下立即需要启动,但是异步执行的生命周期短暂的使用场景。
HandlerThread: 为某些回调方法或者等待某些任务的执行设置一个专属的线程,并提供线程任务的调度机制。
ThreadPool: 把任务分解成不同的单元,分发到各个不同的线程上,进行同时并发处理。
IntentService: 适合于执行由UI触发的后台Service任务,并可以把后台任务执行的情况通过一定的机制反馈给UI。
如果大量操作数据库数据时建议使用批处理操作。如:批量添加数据。
应用启动性能优化。
使用NoHttp获取应用列表
问题表现:通常从用户点击到应用完全展示完首页,需要用户等待一段时间。我们如何缩短时间并提高用户体验。
分析:应用在启动的过程中我们的代码能够影响启动速度的地方如下
Application的onCreate
首屏Activity的渲染
利用Traceview工具观察启动过程方法耗时情况,重点关注onCreate方法(自定义Application和首页Activity)。问题:Traceview工具如何在应用启动时监控数据?
分析自定义Application耗时操作,判断onCreate方法中的内容(如:第三方的工具是否可以不占用主线程进行初始化)。
查看界面是否存在过渡绘制。
利用Hierarchy Viewer工具查看界面需要优化的点。
启动过程中的白屏优化。
第一步:观察耗时情况
1、在onCreate开始和结尾打上trace
Debug.startMethodTracing("POApp");
Debug.stopMethodTracing();
运行程序, 会在sdcard上生成一个”POApp.trace”的文件.
注意:需要给程序加上写存储的权限
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/&
Android6.0以后的模拟器需要为应用打开读写权限
2、通过adb pull将其导出到本地
adb pull /sdcard/ POApp.trace 存放文件路径
第二步:分析数据
通过DDMS的FileàOpen File
查询结果如下
说明:我们使用Real Time/Call进行排序可以得到上图内容
大家可以发现在Application中阻塞主线程干的工作都是NoHttp的初始化工作。为了提高应用的启动速度,我们可以将这个工作放到子线程中完成,通常我们会使用IntentService来处理这个工作。
代码如下:
* Created by itheima.
public class MyApplication extends Application {
public void onCreate() {
super.onCreate();
InitService.start(this);
SystemClock.sleep(1000);
* 将MyApplication中onCreate方法内容耗时的初始化工作移动到该类中
public class InitService extends IntentService {
public static boolean isInit=false;
public InitService() {
super("init");
protected void onHandleIntent(@Nullable Intent intent) {
Logger.setTag("NoHttp");
Logger.setDebug(true);
NoHttp.initialize(this, new NoHttp.Config()
.setConnectTimeout(30 * 1000)
.setReadTimeout(30 * 1000)
isInit=true;
* 启动service
* myApplication
public static void start(MyApplication myApplication) {
Intent intent = new Intent(myApplication, InitService.class);
myApplication.startService(intent);
修改完成后,会引发一个问题,及在首页访问网络时,由于NoHttp的初始化还没有完成会报出如下异常:
如果我们在首页就需要立即访问网络,就需要对初始化进行监控,可以简单的使用一个boolean值,进行判断,当初始化完成后boolean值修改为true。我们在MainActivity中可以使用Handler间隔一段时间就检查一下boolean即可。
第三步:过渡绘制
进入首页后,应用的启动速度限制就集中在首页的界面渲染上了。因此我们开始对界面进行优化处理。
过渡绘制查看结果。
表现还好,我们可以检查一下Item,看看是否可以优化掉一次绘制。
第四步:优化界面布局
Hierarchy Viewer工具派上用场了,我们可以检查一下布局是否合理。
重点观察其中一个条目
优化完成后的结构图
我们先优化掉两个用处不大的LinearLayout,然后在考虑是否可以继续优化掉条目中的LinearLayout。
第五步:Launch screens设置
两种处理方案:
方案一:设置一个背景图
name="android:windowBackground"&@drawable/splash&
name="android:windowNoTitle"&true&
注意:当界面加载完成后需要将背景改成白色。
方案二:设置成透明的界面,制造延时启动效果
name="android:windowIsTranslucent"&true&
name="android:windowNoTitle"&true&
BlockCanary是一个Android平台的一个非侵入式的性能监控组件,应用只需要实现一个抽象类,提供一些该组件需要的上下文环境,就可以在平时使用应用的时候检测主线程上的各种卡慢问题,并通过组件提供的各种信息分析出原因并进行修复。
取名为BlockCanary则是为了向LeakCanary致敬,顺便本库的UI部分是从LeakCanary改来的,之后可能会做一些调整。
新浪微博:
个人博客:
文章:16篇
阅读:44864
文章:38篇
阅读:32734
文章:35篇
阅读:28103
文章:36篇
阅读:58768魅族pro6卡顿怎么办?魅族pro6卡顿现象的解决方法
互联网 & 04-24 10:44:19 & 作者:佚名 &
新买的魅族pro6手机出现卡顿问题怎么办?该如何解决这个问题,对此,本文小编就给大家带来魅族pro6卡顿现象的解决方法,希望可以帮助到大家
魅族pro6卡顿怎么办?很多小伙伴花了2499抢到了魅族PRO6,但是发现用了一段时间后,手机一玩大游戏,就有点卡顿,那么如何解决这个问题呢?下面小编就给大家带来魅族pro6卡顿现象的解决方法,一起来看看吧。
魅族PRO6正式推出之后,不少朋友已经入手了该机,但使用一段时间之后,就会发现手机有些卡顿,来来来,不妨来看看下面提供的几种方法吧~~
魅族Pro6清除后台进程省电延迟续航
具体的方法如下:
1-打开手机的&设置&
2-找到&辅助功能&
3-找到&开发人员工具&
4-将&窗口动画缩放&、&过渡动画缩放&、&动画程序时长调整&、这三项全部设置成&关闭动画& 并将&强制进行GPU渲染&这个选项关闭!
这样设置之后虽然没了动画效果,但是关闭了GPU渲染后续航能力提升了,而且也不会因为关闭了强制GPU渲染变得卡顿了
原因一:开机自启动程序导致手机变慢
手机在使用过程中,会安装很多应用,而这些应用程序会在开机时自动启动,直接导致手机内存被大量占用,而一般用户又不会去注意这个问题,不注意去去除掉那些无用的开机启动项,因此手机随着空间内存的越来越小而变的越来越慢。我们可以通过限制自启动项,来减少手机内存的占用量。
解决方法:对于自启动程序过过造成的卡顿,我们可以使用系统自带的自启动管理(系统与安全&&自启动管理),把不需要的一些程序禁止自启动,这样,我们在开机的时候,就会流畅一些。
原因二:后台进程影响手机速度
我们在手机上使用完一个应用后,通过应用自带的&退出&功能将应用关闭,这个看似已经将应用结束,但实际上却仍在手机后台驻留。而这是普通用户无法发现的问题,这些驻留的应用有的是为了PUSH新消息、等待新任务,而有一些完全没有驻留后台的必要,举个例子,手机淘宝,手机易迅,虽然我们退出了,但有新的消息后,仍然会有提示消息!所以要关闭这些后台进程,以免影响手机速度。
解决方法:对于后台应用进程影响手机速度的问题,结束当前运行的后台进程,简单的一键释放内存。
原因三:系统和应用缓存文件影响手机速度
大量应用在使用的过程中会产生缓存和系统垃圾文件,比如浏览器上网的过程中会产生一些缓存,占用手机内存空间,影响手机的速度。但那些文件是可以删除的垃圾,那些不是,对于一般手机用户来说,又很难分辨。
解决方法:清理手机缓存,大家可以借助360一些第三方软件。
推荐阅读:
以上就是小编带来的魅族pro6卡顿现象的解决方法,希望可以帮助到大家,更多内容请关注脚本之家网站!
大家感兴趣的内容
12345678910
最近更新的内容天涯明月刀掉帧严重怎么办 天涯明月刀掉帧卡顿解决方法
时间: 15:25:45来源:作者:lhy(0)
天涯明月刀已经说正式开测了,很多参与天刀不删档的玩家玩游戏的过程中掉帧情况非常糟糕,但是配置已经足够跑得动游戏了。于是,今天就有大神为我们详细解答了掉帧卡顿的原因,一起来看看他的解决方法吧!具体怎么打开本地安全策略来说一下,WIN7和WIN8有一些小小的区别不过都能打开,下面说说win7如何打开。点击“开始”菜单,在搜索框中输入“运行”回车,即会弹出运行窗口,如下图所示;或者用快捷键Windows+R,同样可以启动运行窗口。在运行窗口中输入“ecpol.msc”,如下图,启动本地安全策略。图片上面的路径是我在吧里找了多位技术宅找到的然后把它们全部整合在了一起。在此感谢各位吧友,这些路径全是腾讯的流氓插件比如QT语音 TP 管家等等!严重影响游戏内帧数禁用后能够大大提高帧数,由于天刀刚开有很多BUG,吧里也有朋友遇到帧数BUG,我实测禁用这些后帧数直接从30跳到60满帧所以带给大家。打开本地安全策略,然后看我图片点到其他规则那里面去。然后新建路径规则,一个一个挨个把图片上面的路径添加进去弄为不允许就可以了。

我要回帖

更多关于 战争雷霆高帧数卡顿 的文章

 

随机推荐