日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 嵌入式 > Linux閱碼場
[導(dǎo)讀]在討論Android性能問題的時候,卡頓、響應(yīng)速度、ANR這三個性能相關(guān)的知識點通常會放到一起來講,因為引起卡頓、響應(yīng)慢、ANR的原因類似,只不過根據(jù)重要程度,被人為分成了卡頓、響應(yīng)慢、ANR三種,所以我們可以定義廣義上的卡頓,包含了卡頓、響應(yīng)慢和ANR三種,所以如果用戶反饋說手...

在討論 Android 性能問題的時候,卡頓、響應(yīng)速度、ANR 這三個性能相關(guān)的知識點通常會放到一起來講,因為引起卡頓、響應(yīng)慢、ANR 的原因類似,只不過根據(jù)重要程度,被人為分成了卡頓、響應(yīng)慢、ANR 三種,所以我們可以定義廣義上的卡頓,包含了卡頓、響應(yīng)慢和 ANR 三種,所以如果用戶反饋說手機卡頓或者 App 卡頓,大部分情況下都是廣義上的卡頓,需要搞清楚,到底出現(xiàn)了哪一種問題


如果是動畫播放卡頓、列表滑動卡頓這種,我們一般定義為 狹義的卡頓,對應(yīng)的英文描述我覺得應(yīng)該是 Jank;如果是應(yīng)用啟動慢、亮滅屏慢、場景切換慢,我們一般定義為 響應(yīng)慢 ,對應(yīng)的英文描述我覺得應(yīng)該是 Slow ;如果是發(fā)生了 ANR,那就是 應(yīng)用無響應(yīng)問題 。三種情況所對應(yīng)的分析方法和解決方法不太一樣,所以需要分開來講


另外在 App 或者廠商內(nèi)部,卡頓、響應(yīng)速度、ANR 這幾個性能指標都是有單獨的標準的,比如 掉幀率、啟動速度、ANR 率等,所以針對這些性能問題的分析和優(yōu)化能力,對開發(fā)者來說就非常重要了


本文是響應(yīng)速度系列的第二篇,主要是以 Android App 冷啟動為例,講解如何使用 Systrace 來分析 App 冷啟動


Systrace (Perfetto) 工具的基本使用如果還不是很熟悉,那么需要優(yōu)先去補一下 Systrace 基礎(chǔ)知識系列[1],本文假設(shè)你已經(jīng)熟悉 Systrace(Perfetto)的使用了


1. 準備工作

這個案例和對應(yīng)的 Systrace 偏工程化一些,省略了很多細節(jié),因為應(yīng)用的啟動流程涉及的知識非常廣,如果每個都細化的話,會有很大的篇幅。推薦大家看這篇文章,非常詳細:Android 應(yīng)用啟動全流程分析[2]


所以這里以 Systrace 為主線,講解應(yīng)用啟動的時候各個關(guān)鍵模塊的大概工作流程。了解大概流程之后,就可以分段去深入自己感興趣或者自己負責(zé)的部分,這里首先放一張 Systrace 和手機截圖所對應(yīng)的圖,大家可以先看看這個圖,然后再往下看(博客里面 Perfetto 和 Systrace 混合使用)


應(yīng)用啟動完整圖為了更方便分析應(yīng)用冷啟動,我們需要做下面的準備工作


  1. 打開 Binder 調(diào)試,方便在 Trace 中顯示 Binder 信息?(即可以在 Systrace 中看到 Binder 調(diào)用的函數(shù))- 需要 Root
    1. 開啟 ipc debug:adb shell am trace-ipc start
    2. 抓取結(jié)束后,可以執(zhí)行下面的命令關(guān)閉?adb shell am trace-ipc stop --dump-file /data/local/tmp/ipc-trace.txt
  2. Trace 命令加入 irq tag,默認的命令不包含 irq,需要自己加 irq 的 TAG,這樣打開 Trace 之后,就可以看到 irq 相關(guān)的內(nèi)容,最后的抓 trace 命令如下:? ?   python /mnt/d/Android/platform-tools/systrace/systrace.py gfx input view webview wm am sm rs bionic power pm ss database network adb idle pdx sched irq freq idle disk workq binder_driver binder_lock -a com.xxx.xxx,注意這里的 com.xxx.xxx 換成自己的包名,如果不是調(diào)試特定的包名,可以去掉 -a com.xxx.xxx
  3. 推薦 :如果要 Debug 的 App 可以進行編譯(即可以使用 Gradle 編譯,一般自己開發(fā)的項目都可以),可以在分析響應(yīng)速度問題的時候,引入 TraceFix 庫(接入方法參考 https://github.com/Gracker/TraceFix)。接入之后,編譯的時候就會進行代碼插樁,在 App 代碼的每一個函數(shù)中都插入 Trace 點,這樣在分析的時候可以看到更詳細的 App 的信息
    1. 使用插件前,只能看到 Framework 里面的 Trace 點
    2. 使用插件后?,可以看到 Trace 中顯示的信息多了很多(App 自身的代碼邏輯,F(xiàn)ramework 的代碼沒法插樁)

2. Android App 冷啟動流程分析

本文以 在桌面上冷啟動一個 Android App 為例,應(yīng)用冷啟動的整個流程包含了從用戶觸摸屏幕到應(yīng)用完全顯示的整個流程,其中涉及到


  1. 觸摸屏中斷處理階段
  2. InputReader 和 InputDispatcher 處理 input 事件階段
  3. Launcher 處理 input 事件階段
  4. SystemServer 處理啟動事件
  5. 啟動動畫
  6. 應(yīng)用啟動和自身邏輯階段
上一篇文章有講到響應(yīng)速度問題,需要搞清楚 起點 和 終點,對于應(yīng)用冷啟動來說,起點就是 input 事件,終點就是應(yīng)用完全展示給用戶(用戶可操作)


下面將從上面幾個關(guān)鍵流程,通過 Systrace 的來介紹整個流程


2.1 觸摸屏中斷處理階段

由于我們的案例是在桌面冷啟動一個 App,那么在手指觸摸手機屏幕的時候,觸摸屏?xí)|發(fā)中斷,這個中斷我們最早能在 Systrace 中看到的地方如下:


對應(yīng)的 cpu ss 區(qū)域和 中斷區(qū)域(加了 irq 的 tag 才可以看到)


一般來說,點擊屏幕會觸發(fā)若干個中斷,這些信號經(jīng)過處理之后,觸摸屏驅(qū)動會把這些點更新到 EventHub 中,讓 InputReader 和 InputDIspatcher 進行進一步的處理。這一步一般不會出現(xiàn)什么問題,廠商這邊對觸摸屏的調(diào)教可能會關(guān)注這里


2.2 InputReader 和 InputDispatcher 處理 Input 事件階段

InputReader 和 InputDispatcher 這兩個線程跑在 SystemServer 里面,專門負責(zé)處理 Input 事件,具體的流程可以參考Android Systrace 基礎(chǔ)知識 - Input 解讀[3] 這篇文章


InputReader 和 InputDispatcher這里由于我們是點擊桌面上的一個 App 的圖標,可以看到底層上報上來的事件包括一個 Input_Down 事件 若干個 Input Move 事件 一個 Input Up 事件,組成了一個完整的點擊事件


由于 Launcher 在進程創(chuàng)建的時候就注冊了 Input 監(jiān)聽,且此時 Launcher 在前臺且可見,所以 Launcher 進程可以收到這些 Input 事件,并根據(jù) Input 事件的類型進行處理,input 事件在 SystemServer 和 App 的流轉(zhuǎn)在 Systrace 中的具體表現(xiàn)可以參考 Android Systrace 基礎(chǔ)知識 - Input 解讀[4] ,這里把核心的兩張圖放上來


2.2.1 Input 事件在 SystemServer 中流轉(zhuǎn)

看下圖即可,如果要看更詳細的,可以查看 Android Systrace 基礎(chǔ)知識 - Input 解讀[5]


Input 事件在 SystemServer 中流轉(zhuǎn)

2.2.2 Input 事件在 Launcher 進程流轉(zhuǎn)

看下圖即可,如果要看更詳細的,可以查看 Android Systrace 基礎(chǔ)知識 - Input 解讀[6]


2.3 Launcher 進程處理 Input 事件階段

Launcher 處理 Input 事件也是響應(yīng)時間的一個重要階段,主要包括兩個響應(yīng)速度指標


  1. 點擊桌面到桌面第一幀響應(yīng)(一般 Launcher 會在接收到 Down 事件的時候,將 App 圖標置灰,以表示接收到了事件;有的定制桌面 App 圖標會有一個縮小的動畫,表示被按壓)
  2. 桌面第一幀響應(yīng)到啟動 App(這段時間指的是桌面在收到 Down 對 App 圖標做處理后,到收到 Up 事件判斷需要啟動 App 的時間)
另外提一下,滑動桌面到桌面第一幀響應(yīng)時間(這個指的是滑動桌面的場景,左右滑動桌面的時候,用高速相機拍攝,從手指動開始,到桌面動的第一幀的時間)也是一個很重要的響應(yīng)速度指標,部分廠商也會在這方面做優(yōu)化,感興趣的可以自己試試主流廠商的桌面滑動場景(跟原生的機器對比 Systrace 即可)


在冷啟動的場景里面,Launcher 在收到 up 事件后,會進行邏輯判斷,然后啟動對應(yīng)的 App(這里主要是交給 AMS 來處理,又回到了 SystemServer 進程)


Launcher 處理 input 事件這個階段通常也是做系統(tǒng)優(yōu)化的會比較關(guān)注,做 App 的同學(xué)還不需要關(guān)注到這里(Launcher App 的除外);另外在最新的版本,應(yīng)用啟動的動畫是由 Launcher 和 SystemServer 共同完成的,目的就是可以做一些復(fù)雜的動畫而沒有割裂感,大家可以用慢鏡頭拍一下啟動時候和退出應(yīng)用的動畫,可以看到有的應(yīng)用圖標是分層的,甚至?xí)?,這是之前純粹由 SystemServer 這邊來做動畫所辦不到的


2.4 SystemServer 處理 StartActivity 階段

SystemServer 處理主要是有2部分


  1. 處理啟動命令
  2. 通知 Launcher 進入 Pause 狀態(tài)
  3. fork 新的進程

處理啟動命令

這個 SystemServer 進程中的 Binder 調(diào)用就是 Launcher 通過 ActivityTaskManager.getService().startActivity 調(diào)用過來的


fork 新的進程,則是在判斷啟動的 Activity 的 App 進程沒有啟動后,需要首先啟動進程,然后再啟動 Activity,這里是冷啟動和其他啟動不一樣的地方。fork 主要是 fork  Zygote64 這個進程(部分 App 是 fork 的 Zygote32 )


fork 新進程fork 新進程對應(yīng)的代碼

Zygote 64 位進程執(zhí)行 Fork 操作

對應(yīng)的 App 進程出現(xiàn)

對應(yīng)的代碼如下,這里就正式進入了 App 自己的進程邏輯了


應(yīng)用啟動后,SystemServer 會記錄從 startActivity 被調(diào)用到應(yīng)用第一幀顯示的時長,在 Systrace 中的顯示如下(注意結(jié)尾是應(yīng)用第一幀,如果應(yīng)用啟動的時候是 SplashActivity -> MainActivity,那么這里的結(jié)尾只是 SplashActivity,MainActivity 的完全啟動需要自己查看)


2.5 應(yīng)用進程啟動階段

通常的大型應(yīng)用,App 冷啟動通常包括下面三個部分,每一個部分耗時都會導(dǎo)致應(yīng)用的整體啟動速度變慢,所以在優(yōu)化啟動速度的時候,需要明確知道應(yīng)用啟動結(jié)束的點(需要跟測試溝通清楚,一般是界面保持穩(wěn)定的那個點)


  1. 應(yīng)用進程啟動到 SplashActivity 第一幀顯示(部分 App 沒有 SplashActivity,所以可以省略這一步,直接到進程啟動到 主 Activit 第一幀顯示 )
  2. SplashActivity 第一幀顯示到主 Activity 第一幀顯示
  3. 主 Activity 第一幀顯示到界面完全顯示
下面針對這三個階段來具體分析(當(dāng)然你的 App 如果簡單的話,可能沒有 SplashActivity ,直接進的就是主 Activity,那么忽略第二步就可以了)


應(yīng)用進程啟動到 SplashActivity 第一幀顯示

由于是冷啟動,所以 App 進程在 Fork 之后,需要首先執(zhí)行 bindApplication ,這個也是區(qū)分冷熱啟動的一個重要的點。Application 的環(huán)境創(chuàng)建好之后,就開始組件的啟動(這里是 Activity 組件,通過 Service、Broadcast、ContentProvider 組件啟動的進程則會在 bindApplication 之后先啟動這些組件)


Activity 的生命周期函數(shù)會在 Activity 組件創(chuàng)建的時候執(zhí)行,包括 onStart、onCreate、onResume 等,然后還要經(jīng)過一次 Choreographer#doFrame 的執(zhí)行(包括 measure、layout、draw)以及 RenderThread 的初始化和第一幀任務(wù)的繪制,再加上 SurfaceFlinger 一個 Vsync 周期的合成,應(yīng)用第一幀才會真正顯示(也就是下圖中 finishDrawing 的位置),這部分詳細的流程可以查看 Android Systrace 基礎(chǔ)知識 - MainThread 和 RenderThread 解讀[7]


SplashActivity 第一幀顯示到主 Activity 第一幀顯示

大部分的 App 都有 SplashActivity 來播放廣告,播放完成之后才是真正的主 Activity 的啟動,同樣包括 Activity 組件的創(chuàng)建,包括 onStart、onCreate、onResume 、自有啟動邏輯的執(zhí)行、WebView 的初始化等等等等,直到主 Activity 的第一幀顯示


主 Activity 第一幀顯示到界面完全加載并顯示

一般來說,主 Activity 需要多幀才能顯示完全,因為有很多資源(最常見的是圖片)是異步加載的,第一幀可能只加載了一個顯示框架、而其中的內(nèi)容在準備好之后才會顯示出來。這里也可以看到,通過 Systrace 不是很方便來判斷應(yīng)用冷啟動的終點(除非你跟測試約定好,在某個 View 顯示之后就算啟動完成,然后你在這個 View 里面打個 Systrace 的 Tag,通過跟蹤這個 Tag 就可以粗略判斷具體 Systrace 里面哪一幀是啟動完成的點)


我制作了一個 Systrace 截圖的方式,來進行演示,方便你了解 App 啟動各個階段都對應(yīng)在 Systrace 的哪里(使用的是一個開源的 WanAndroid 客戶端)


App 啟動圖,結(jié)合了 Systrace 和 屏幕截圖

End

本文重點放在了如何在 Systrace 中展示 App 的完整冷啟動流程,方便大家在做 App 的啟動優(yōu)化的時候,可以通過 Systrace 來快速定位到啟動瓶頸,也方便進行競品的對比和分析,


  1. 至于如何分析,可以查看 Systrace 響應(yīng)速度實戰(zhàn) 1 :了解響應(yīng)速度原理[8] 的分析套路部分
  2. 至于如何優(yōu)化,可以查看 Android App 啟動優(yōu)化全記錄[9] 這篇文章,這里就不再重復(fù)了。不過隨著技術(shù)的發(fā)展,有些優(yōu)化手段會消失,而會有新的優(yōu)化手段冒出來,我也會對這篇文章進行維護,如果大家發(fā)現(xiàn)新的優(yōu)化技術(shù),麻煩博客留言或者加微信(553000664)通知我,我來進行調(diào)研和更新



本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除( 郵箱:macysun@21ic.com )。
換一批
延伸閱讀
關(guān)閉