IdleHandler,頁面啟動最佳化神器
隨著App的開發到了某個階段必然會遇到一個需求,那就是最佳化頁面的啟動時間。
第一個問題:有什麼方法可以去統計頁面的啟動時間呢?
adb logcat -s ActivityManager | grep "Displayed"
上面的命令列可用來進行檢視。
第二個問題:啟動時間是包括了哪些流程,是如何被計算出來的呢?
App啟動主要經過如下幾個流程
Launch the process.
Initialize the objects.
Create and initialize the activity.
Inflate the layout.
Draw your application for the first time.
最末尾的步驟5是繪製你的介面。所以完整的啟動時間是要到繪製完成為止。
那麼繪製介面對應的是什麼時候呢?一般我們開發,最晚能被回撥的是在onResume方法,那麼onResume方法是在繪製之後還是之前呢?
no code no truth
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) { //省略部分程式碼 r = performResumeActivity(token, clearHide, reason); //省略部分程式碼 if (a.mVisibleFromClient) { if (!a.mWindowAdded) { a.mWindowAdded = true; wm.addView(decor, l);
看上面的程式碼,就先放結論了。
在performResumeActivity 中進行了onResume的回撥,在wm.addView 中進行了繪製,因此onResume的方法是在繪製之前,在onResume中做一些耗時操作都會影響啟動時間。
下面就剝一下onResume的邏輯,繪製的有興趣可以自己看原始碼。 首先performResumeActivity中會呼叫r.activity.performResume();
public final ActivityClientRecord performResumeActivity(IBinder token, boolean clearHide, String reason) { //省略部分程式碼 try { r.activity.onStateNotSaved(); r.activity.mFragments.noteStateNotSaved(); checkAndBlockForNetworkAccess(); if (r.pendingIntents != null) { deliverNewIntents(r, r.pendingIntents); r.pendingIntents = null; } if (r.pendingResults != null) { deliverResults(r, r.pendingResults); r.pendingResults = null; } r.activity.performResume(); //省略部分程式碼 } }
然後在performResume中呼叫了 mInstrumentation.callActivityOnResume(this);
final void performResume() { //省略部分程式碼 mInstrumentation.callActivityOnResume(this); //省略部分程式碼 }
最後在callActivityOnResume 呼叫了onResume
public void callActivityOnResume(Activity activity) { activity.mResumed = true; activity.onResume(); //省略程式碼 }
到了此處就算真正呼叫到了onResume的方法。
既然知道了onResume中做的操作會影響到啟動時間,那麼就有一個最佳化啟動時間的思路了。
思路
把在onResume以及其之前的呼叫的但非必須的事件(如某些介面View的繪製)挪出來找一個時機(即繪製完成以後)去呼叫。那樣啟動時間自然就縮短了。但是整體做的事並沒有明顯變化。那麼這個時機是什麼呢?
IdleHandler
看下IdleHandler的原始碼
/** * Callback interface for discovering when a thread is going to block * waiting for more messages. */ public static interface IdleHandler { /** * Called when the message queue has run out of messages and will now * wait for more. Return true to keep your idle handler active, false * to have it removed. This may be called if there are still messages * pending in the queue, but they are all scheduled to be dispatched * after the current time. */ boolean queueIdle(); }
從這個原始碼可知道,IdleHandler即在looper裡面的message處理完了的時候去呼叫,這不就是我們onResume呼叫完了以後的時機麼。
來一張圖說明一下,明顯的IdleHandler在onResume以及performTraversals繪製之後呼叫
由這個思路我把自己負責的頁面中的一些介面的繪製邏輯挪到了IdleHandler中,由於有LoadingView時間,我把Adapter的繫結也挪出去了。看下最佳化前後效果圖 ,效果還是挺明顯的;
作者:Android高階架構
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2730/viewspace-2821712/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- IdleHandler,頁面啟動優化神器優化
- App啟動頁面優化APP優化
- android app 啟動第一個頁面AndroidAPP
- 簡單頁面開發神器——畫容
- 頁面CLS 最佳化實踐
- 頁面壞UV效能最佳化
- 在阿里雲快速啟動Appsmith搭建前端頁面阿里APPMIT前端
- Chrome外掛—CSDN部落格頁面優化神器Chrome優化
- win10如何更改啟動頁面_win10要怎樣修改開機啟動畫面Win10動畫
- 頁面開啟很正常,後臺return後頁面偏左了
- 前端面試題 — 前端頁面效能最佳化前端面試題
- Android頁面啟動速度優化工具專案:and-load-aotAndroid優化
- 基於Html對父頁面開啟子頁面Dialog()的使用HTML
- react跳轉url,跳轉外鏈,新頁面開啟頁面React
- VS Code 快捷開啟PHP頁面PHP
- Effective前端--加快頁面開啟速度前端
- Flutter SingleChildScrollView 滾動頁面FlutterView
- 頁面圖片自動滾動
- 移動端活動頁面搭建
- 得物面試:MySQL 深度分頁如何最佳化?面試MySql
- Mac APP快速啟動及切換神器:ManicoMacAPP
- Manico for Mac APP快速啟動及切換神器MacAPP
- Android 網頁開啟App進入對應頁面Android網頁APP
- XAF自定義啟動頁
- 預設瀏覽器設定及vue自動開啟頁面瀏覽器Vue
- 【easyui】開啟的tab頁同頁面引數不同頁面內容不重新整理UI
- vue頁面有彈層,禁止頁面滾動Vue
- 404頁面自動跳轉到首頁
- 用H5頁面開啟APPH5APP
- DiscuzQ動態頁面SEO方案
- 禁止頁面滾動的方法
- 遮罩層禁止頁面滾動遮罩
- 頁面旋轉動畫效果動畫
- Tomcat啟動後頁面可以正常訪問 介面路徑報錯404Tomcat
- centos7伺服器tomcat啟動正常,但是訪問頁面404CentOS伺服器Tomcat
- 淺談App的啟動最佳化APP
- Linux啟動時間最佳化技巧Linux
- 微軟出品自動化神器【Playwright+Java】系列(九)多執行緒、重定向、彈出新視窗、截圖、新頁面、錄製、頁面物件模式操作微軟Java執行緒物件模式