Android提升進入界面的速度


應用除了有內存占用、內存泄露、內存抖動等看不見的性能問題外,還有很多看得見的性能問題,比如進入界面慢、點擊反應慢、頁面卡頓等等,這些看得見的體驗問題會嚴重影響用戶使用APP心情,但用戶的情緒又無法通過異常采集、數據分析來發現,盡早優化APP的性能體驗問題非常重要,會在一定程度上提升用戶的留存率。

  本文結合最近一段時間對項目中APP各界面進入速度的優化,總結一下進入界面慢的優化方案。

先從Activity的生命周期說起

  從一個界面FirstActivity跳轉到另外一個界面SecondActivity,兩個Activity的生命周期流程是這樣的:

頁面跳轉生命周期的流程

  應用必須在走完FirstActivity的onPause方法后才會跑SecondActivity的onCreate方法,FirstActivity的onStop和onDestory方法不會影響到進入SecondActivity的速度。如果我們要優化從FirstActivity跳轉到SecondActivity的速度,需要從FristActivity的onPause和SecondActivity的onCreate、onStart和onResume方法入手。onStart方法通常干的事情比較少,頁面之間跳轉慢主要是因為在FirstActivity的onPause和SecondActivity的onCreate、onResume方法耗時導致,這個過程需要執行的操作主要有:

  • 保存FirstActivity界面中的一些狀態;

  • 加載SecondActivity的布局;

  • 初始化SecondActivity。

  針對上面的分析我們可以從如下四個方面入手:

  • 耗時任務異步處理;

  • 布局文件優化;

  • 不可見視圖需要時加載;

  • 應用內慎用多進程。

優化實踐

耗時任務異步處理

  除了Android明令禁止在UI線程中執行網絡操作外,還有一些耗時的操作也不能在UI線程中執行,比如IO操作、耗時較長的邏輯操作(比如算法),在Android中可以通過如下幾種方式來實現異步任務:

  • AsyncTask

  • Thread

  • Timer,TimerTask

  • Handler

  如果是在執行異步任務后需要更新界面,優先考慮使用AsyncTask和Handler,它們提供了刷新UI的方案;如果是定時任務可以考慮使用Handler和Timer,TimerTask;如果是使用Thread和Timer,TimerTask,更新UI時可以通過執行當前Activity的runOnUiThread方法實現更新UI操作。

布局文件優化 ViewStub

  在優化過程中發現有的界面光是加載布局就需要500ms左右,再加上界面的初始化和上一個界面的狀態保存操作,頁面跳轉時會有嚴重的遲滯感,對於布局文件的優化網上有很多有價值的文章,最重要的兩條是:

  • 布局文件不要嵌套太深;

  • 對於不需要進入界面就需要顯示的視圖,強烈建議使用ViewStub。

  布局文件嵌套太深標示着需要更多次的布局、測量和繪制,會導致耗時更多,這個可以使用android自帶的“hierarchyviewer”查看,邊優化邊看效果;但有時候即使布局足夠扁平,加載布局文件時還是會比較耗時,因為布局文件中的視圖太多了,此時對於不需要進入界面就需要顯示的視圖,可以使用ViewStub來延遲加載,比如加載的進度條、特定狀態下出現的倒計時和動畫等,ViewStub的使用方式如下:

/** * 在需要使用下載進度條的地方調用該方法加載下載進度條的布局 */ private void initDownloadProgress() { if(null == mDownloadViewStub){ mDownloadViewStub = (ViewStub)findViewById(R.id.downProgressViewStubId); View view = mDownloadViewStub.inflate(); mDownloadProgressLayout = (RelativeLayout) view.findViewById(R.id.progressBackLayoutId); mDownLoadProgressBar = (ArrowProgressBar) view.findViewById(R.id.arrowProgressBarId); mDownloadProgressLayout.setVisibility(View.GONE); mDownloadProgressLayout.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return true; } }); } }

不可見視圖需要時加載

  除了布局文件的優化外,代碼中不需要立即顯示的視圖和動畫都做成延遲加載,比如AnimationDrawable、TypedArray數組、Typeface、addView等,值得一提的是,初始化AnimationDrawable、TypedArray數組和Typeface會很耗時,並且AnimationDrawable特別耗內存,如果不是進入界面就需要使用,強烈建議在需要使用的地方再初始化,分開初始化可以大大減小頁面初始化的耗時。

應用內慎用多進程

  從FirstActivity跳轉到SecondActivity,如果這兩個界面不屬於同一個進程,首次跳轉的時候會創建一個新的進程,創建進程是比較耗時的,比跳轉到同一進程內的新頁面耗時更多,如果不是必須要在應用內使用多進程,強烈建議不要在應用內使用多進程。

總結

  性能優化是一個持續的過程,界面跳轉效率只是一個性能指標,更快地跳轉對於用戶來說有着更好地體驗,優化界面跳轉速度的步驟如下:

  • 打印執行每一段代碼執行需要的時間;

  • 找到耗時較多的代碼段,可能是setContentView,也有可能是在UI線程中的其它耗時操作;

  • 根據耗時的代碼段找解決辦法;

  • 優化后運行看效果。

特別說明:

  • 初始化AnimationDrawable、TypedArray數組和Typeface會很耗時,並且AnimationDrawable特別耗內存,一定要注意他們的初始化時機;

  • 不要迷信網上的一些優化技巧,一定要結合親身實踐,看數據說話;

  • 只要認真分析,很多地方都會有優化空間,將優化的經驗總結出來,並運用到后續的開發中;

  • 優化APP的性能問題在一定程度上能夠提高用戶的留存率,是一件很有價值的事情。

轉自:張明雲


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM