簡(jiǎn)介
本文是主要是記錄作者調(diào)優(yōu)app的過(guò)程記錄溶诞,旨在記錄荞下,不在文采
調(diào)試界面是否存在過(guò)度繪制枪萄?
過(guò)度繪制就是一個(gè)像素點(diǎn)重復(fù)繪制的次數(shù)太多隐岛,比如你的App登錄視圖有View1、View2瓷翻、View3...聚凹,并且這三個(gè)組件的寬高屬性都是match_parent,相當(dāng)于都重疊在一起了齐帚,而我們只能看到最上面的那一個(gè)view妒牙,這就是過(guò)度繪制
使用系統(tǒng)的GPU調(diào)試功能
打開(kāi)設(shè)置->開(kāi)發(fā)者選項(xiàng)->調(diào)試GPU過(guò)度繪制,打開(kāi)后App呈現(xiàn)這種狀態(tài):
tips:
- 沒(méi)有顏色 - 表示一個(gè)像素點(diǎn)只繪制了一次童谒,顯示自己本來(lái)的顏色
- 藍(lán)色 - 1倍過(guò)度繪制单旁,即一個(gè)像素點(diǎn)繪制了 2 次;
- 綠色 - 2倍過(guò)度繪制饥伊,即一個(gè)像素點(diǎn)繪制了 3 次象浑;
- 淺紅色 - 3倍過(guò)度繪制蔫饰,即一個(gè)像素點(diǎn)繪制了 4 次;
- 深紅色 - 4倍過(guò)度繪制及以上愉豺,即一個(gè)像素點(diǎn)繪制了 5 次及以上篓吁;
判斷一個(gè)頁(yè)面是否過(guò)度繪制,有兩個(gè)準(zhǔn)側(cè):
應(yīng)用所有界面以及分支界面均不存在超過(guò)4X過(guò)度繪制(深紅色區(qū)域)蚪拦;
應(yīng)用所有界面以及分支界面下杖剪,3X過(guò)度繪制總面積(淺紅色區(qū)域)不超過(guò)屏幕可視區(qū)域的1/4;
解決過(guò)度繪制:
方法一 --- 利用工具解析:
使用Android sdk提供的Hierarchy View工具分享布局的層級(jí)視圖驰贷,查看是否有多個(gè)界面重疊在一起盛嘿;由于商業(yè)版本的手機(jī)出于安全考慮,Android系統(tǒng)底層屏蔽了Hierarchy調(diào)試功能導(dǎo)致Hierarchy無(wú)法連接手機(jī)括袒;可以root修改源碼解決次兆,樓主覺(jué)得麻煩就沒(méi)去做了,如對(duì)此辦法感興趣可以自行百度
方法二 --- 自行分析視圖結(jié)構(gòu)
自己分析自己的代碼邏輯锹锰、視圖結(jié)構(gòu)芥炭,找出其中過(guò)度繪制的地方;樓主就是用的這種笨方法恃慧,經(jīng)過(guò)我的查看园蝠,發(fā)現(xiàn)我的代碼里面有用到一個(gè)側(cè)滑的開(kāi)源組件,而這個(gè)側(cè)滑組件根視圖如下:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<ImageView
android:id="@+id/iv_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="centerCrop"/>
<ImageView
android:id="@+id/iv_shadow"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/shadow"
android:scaleType="fitXY"/>
<RelativeLayout
android:id="@+id/sv_menu_holder"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</RelativeLayout>
</merge>
上面就是三個(gè)組件全是match_parent痢士,這就是元兇彪薛,三個(gè)重疊一起大致過(guò)度繪制了;由于前兩個(gè)組件涉及其他的邏輯代碼良瞧,為了減少不必要的麻煩陪汽,直接將前兩個(gè)屬性
android:visibility="gone"
即可解決過(guò)度繪制,效果如下:
總結(jié)
- 不要讓多個(gè)視圖重疊進(jìn)行布局
- Activity選擇主題時(shí)褥蚯,主題會(huì)默認(rèn)屏幕繪制一次挚冤,如果你的布局xml根視圖又添加了一個(gè)background熟悉,可以去把主題里面的windowbackground設(shè)置為null赞庶,如下:
<style name="noBgStyle" parent="AppTheme.NoActionBar">
<item name="android:windowBackground">@null</item>
</style>
- 一定要注意background這個(gè)屬性训挡,加一個(gè)就表示要繪制一層,不僅僅影響過(guò)度繪制歧强,也會(huì)影響下面講的渲染
調(diào)試界面的渲染
Android系統(tǒng)繪制一幀數(shù)據(jù)畫(huà)面盡可能在16ms內(nèi)完成澜薄,如果超過(guò)16ms,就有可能出現(xiàn)掉幀摊册、卡頓的情況肤京,所以Android系統(tǒng)提供了一個(gè)追蹤渲染性能查案功能
打開(kāi)渲染調(diào)試:
設(shè)置->開(kāi)發(fā)者模式->GPU顯示配置文件->以條的形式顯示于屏幕
打開(kāi)后效果會(huì)像這樣:
圖片底部的柱狀圖表示最近128幀的圖像所消耗的時(shí)間,每一個(gè)柱子代表一幀數(shù)據(jù)茅特,每個(gè)柱子三種顏色:
- 藍(lán)色:更新視圖花費(fèi)了多少時(shí)間忘分,類(lèi)似于onDraw方法
- 紅色:OpenGL 渲染 Display List 所需要的時(shí)間棋枕。通俗來(lái)說(shuō),就是記錄了執(zhí)行視圖繪制的耗時(shí)妒峦。用代碼語(yǔ)言來(lái)說(shuō)重斑,就是 Android 用 OpenGL ES 的 API 接口進(jìn)行 2D 渲染 Display List 的時(shí)間
- 黃色:黃色代表的是這一幀 CPU 等待 GPU 處理的時(shí)間。通俗來(lái)說(shuō)肯骇,就是 CPU 等待 GPU 發(fā)出接到命令的回復(fù)的等待時(shí)間窥浪。用代碼語(yǔ)言來(lái)說(shuō),就是這是一個(gè)阻塞調(diào)用笛丙。
水平還有一根綠色的線漾脂,這根線代表16ms,每一幀所消耗的時(shí)間盡量不超過(guò)這條綠線若债;
tips:
一般情況下符相,一個(gè)頁(yè)面的柱子顯示了128個(gè)就應(yīng)該停止了拆融,但是樓主在App打開(kāi)登錄頁(yè)面的時(shí)候蠢琳,這個(gè)柱子一直在刷新,就表示這個(gè)界面不停的在繪制镜豹,就覺(jué)得奇怪了傲须,為什么會(huì)重新繪制,檢查代碼也沒(méi)有發(fā)現(xiàn)自己有重復(fù)繪制的代碼趟脂,最后才發(fā)現(xiàn):
像EditText這類(lèi)可以自動(dòng)獲取焦點(diǎn)的組件泰讽,打開(kāi)后是默認(rèn)獲取焦點(diǎn)的,獲取焦點(diǎn)后昔期,可能是系統(tǒng)為了顯示輸入文字已卸,就不停的刷新頁(yè)面;解決辦法就是默認(rèn)進(jìn)來(lái)不給EditText焦點(diǎn)硼一,給一些根視圖焦點(diǎn)就不會(huì)出現(xiàn)上面不停刷新問(wèn)題