Android 優(yōu)化之卡頓優(yōu)化的實(shí)現(xiàn)
Android 系統(tǒng)每隔 16ms 會發(fā)出 VSYNC 信號重繪界面(Activity)。之所以是 16ms,是因?yàn)?Android 設(shè)定的刷新率是 60FPS(Frame Per Second),也就是每秒 60 幀的刷新率,約合 16ms 刷新一次。
這就意味著,我們需要在 16ms 內(nèi)完成下一次要刷新的界面的相關(guān)運(yùn)算,以便界面刷新更新。
假設(shè)我們更新屏幕的背景圖片需要 24ms 來做這次運(yùn)算,當(dāng)系統(tǒng)在第一個(gè) 16ms 時(shí)刷新界面,由于運(yùn)算還沒有結(jié)束,無法繪出圖片。當(dāng)系統(tǒng)隔 16ms 再發(fā)一次 VSYNC 信息重繪界面時(shí),用戶才會看到更新后的圖片。也就是說 32ms 后才看到了這次刷新(并不是 24ms),這就是丟幀(dropped frame)。
丟幀給用戶的感覺就是卡頓,而且如果運(yùn)算過于復(fù)雜,丟幀會更多,導(dǎo)致界面常常處于停滯狀態(tài)。
卡頓原因
過于復(fù)雜的布局
- 界面性能取決于 UI 的渲染性能,UI 渲染的整個(gè)過程由 CPU 和 GPU 兩個(gè)部分協(xié)同完成。CPU 負(fù)責(zé) UI 布局元素的 Measure、Layout、Draw 等相關(guān)運(yùn)算執(zhí)行,GPU負(fù)責(zé)柵格化(rasterization),將 UI 元素繪制到屏幕上。
- 如果 UI 布局層次太深,或是自定義控件的 onDraw 中有復(fù)雜運(yùn)算,CPU 的相關(guān)運(yùn)算就可能大于 16ms,導(dǎo)致卡頓。
過度繪制
UI 線程的復(fù)雜運(yùn)算
- UI 線程的復(fù)雜運(yùn)算會造成 UI 無響應(yīng),導(dǎo)致 ANR,但更多的是造成 UI 響應(yīng)停滯卡頓,ANR 是卡頓的極致。
頻繁的 GC
優(yōu)化方法
1、減少刷新次數(shù)
比如進(jìn)度更新,要進(jìn)度有變化再去刷新,且保證頻率不得高于系統(tǒng)的刷新頻率。
2、避免非必要的刷新
若控件不可見,則無需刷新。
3、避免后臺線程影響
如列表控件,在滑動時(shí)不要去加載圖片,可以在滑動監(jiān)聽里停止圖片的加載。
4、局部刷新
如 RecyclerView 的 DiffUtil。自定義 View 可以使用下面兩個(gè)方法:
invalidate(Rect dirty); invalidate(int left, int top, int right, int bottom);
5、盡量使用屬性動畫,它減少了自身的重繪。最后要清除
StringBuilder,List 等在創(chuàng)建時(shí)傳入一個(gè)合適的參數(shù)指定初始容量,以避免頻繁擴(kuò)容的開銷。
6、開啟硬件加速
7、原理可見 Android硬件加速原理與實(shí)現(xiàn)簡介,理解Android硬件加速原理的小白文
Application 級別
<application android:hardwareAccelerated="true" />
Activity 級別
<activity android:hardwareAccelerated="true" />
Window 級別
getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
View 級別
// 如果是 software,會將 View 繪制到一個(gè) Bitmap, // 然后依然是通過硬件加速將 Bitmap 繪制到 Canvas view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
- LAYER_TYPE_NONE:普通渲染方式,不會返回一個(gè)離屏的緩沖,默認(rèn)值。
- LAYER_TYPE_HARDWARE:如果這個(gè)應(yīng)用使用了硬件加速,這個(gè) View 將會在硬件中渲染為 硬件紋理,如果應(yīng)用程序并沒有被硬件加速,則其效果和 LAYER_TYPE_SOFTWARE 相同。
- LAYER_TYPE_SOFTWARE:此 View 通過軟件渲染為一個(gè) Bitmap。
檢查是否開啟了硬件加速
view.isHardware-Accelerated(); Canvas.isHardwareAccelerated();
如果 View 中要處理中文長文本,需要關(guān)閉硬件加速。因?yàn)槊總€(gè)中文編碼不一樣,緩存效果不理想。
監(jiān)控
- 《Android 應(yīng)用性能優(yōu)化最佳實(shí)踐》2.8 章,主要利用 MainLooper 里的 Printer。
- BlockCanary 開源庫
- StrctMode
ANR
Activity 的 View:5 秒無響應(yīng)
BroadcastReceiver:10 秒無響應(yīng)
Service:20 秒無響應(yīng)
ANR 時(shí),系統(tǒng)會生成一個(gè) traces.txt 的文件放在 /data/anr/ 下。通過 adb 命令將其導(dǎo)出到本地
$adb pull data/anr/traces.txt ~/Desktop
UI 線程做耗時(shí)操作,內(nèi)存泄露導(dǎo)致內(nèi)存不足都可能產(chǎn)生 ANR。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android仿微信activity滑動關(guān)閉效果
這篇文章主要為大家詳細(xì)介紹了Android仿微信activity滑動關(guān)閉的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01詳解Android業(yè)務(wù)組件化之URL Schema使用
這篇文章主要為大家詳細(xì)介紹了Android業(yè)務(wù)組件化之URL Schema使用,感興趣的小伙伴們可以參考一下2016-09-09關(guān)于Android 4.4相機(jī)預(yù)覽、錄像花屏的問題的解決方法
這篇文章主要介紹了關(guān)于Android 4.4相機(jī)預(yù)覽、錄像花屏的問題的解決方法,非常不錯,具有參考借鑒價(jià)值,需要的朋友參考下吧2016-12-12Android Studio 3.3.2 正式版的安裝教程圖解
這篇文章主要介紹了Android Studio 3.3.2 正式版的安裝教程圖解,本文分步驟通過圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下2020-02-02Android運(yùn)用BroadcastReceiver實(shí)現(xiàn)強(qiáng)制下線
本篇文章主要介紹了Android運(yùn)用BroadcastReceiver實(shí)現(xiàn)強(qiáng)制下線,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07android實(shí)現(xiàn)添加耳機(jī)狀態(tài)圖標(biāo)的方法
這篇文章主要介紹了android實(shí)現(xiàn)添加耳機(jī)狀態(tài)圖標(biāo)的方法,較為詳細(xì)的分析了Android實(shí)現(xiàn)添加耳機(jī)圖標(biāo)的原理與相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10Android 個(gè)人理財(cái)工具五:顯示賬單明細(xì) 上
本文主要介紹 Android 個(gè)人理財(cái)工具顯示賬單明細(xì),這里提供了示例代碼,和實(shí)現(xiàn)效果圖,幫助大家學(xué)習(xí)理解ListView的用法,有興趣的小伙伴可以參考下2016-08-08Android獲取實(shí)時(shí)連接熱點(diǎn)的設(shè)備IP
這篇文章主要介紹了Android獲取實(shí)時(shí)連接熱點(diǎn)的設(shè)備IP 的相關(guān)資料,文中給大家補(bǔ)充介紹了安卓獲取接入的Wifi熱點(diǎn)設(shè)備的Ip地址的代碼,需要的朋友可以參考下2018-01-01詳解Android App中的AsyncTask異步任務(wù)執(zhí)行方式
這篇文章主要介紹了Android App中的AsyncTask異步任務(wù)執(zhí)行方式,文中舉了一個(gè)打開網(wǎng)絡(luò)圖片的例子幫助大家直觀理解,需要的朋友可以參考下2016-04-04詳解Flutter網(wǎng)絡(luò)圖片本地緩存的實(shí)現(xiàn)
這篇文章主要為大家介紹了詳解Flutter網(wǎng)絡(luò)圖片本地緩存的實(shí)現(xiàn)示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04