標籤:call apple man manifest ade 解釋 效能 文獻 storage
Android效能最佳化系列之布局最佳化
Android效能最佳化系列之記憶體最佳化
Android效能最佳化系列之apk瘦身
應用的啟動速度緩慢是我們在開發過程中常常會遇到的問題,比方啟動緩慢導致的黑屏。白屏問題,本篇部落格就將介紹App啟動最佳化的相關知識。
應用的啟動方式
通常來說,啟動方式分為兩種:冷啟動和暖開機。
1、冷啟動:當啟動應用時。後台沒有該應用的進程。這時系統會又一次建立一個新的進程分配給該應用。這個啟動方式就是冷啟動。
冷啟動由於系統會又一次建立一個新的進程分配給它。所以會先建立和初始化Application類,再建立和初始化MainActivity類(包含一系列的測量、布局、繪製),最後顯示在介面上。
2、暖開機:當啟動應用時,後台已有該應用的進程(例:按back鍵、home鍵,應用儘管會退出,可是該應用的進程是依舊會保留在後台,可進入工作清單查看)。所以在已有進程的情況下,這樣的啟動會從已有的進程中來啟動應用,這個方式叫暖開機。暖開機由於會從已有的進程中來啟動,所以暖開機就不會走Application這步了。而是直接走MainActivity(包含一系列的測量、布局、繪製),所以暖開機的過程僅僅須要建立和初始化一個MainActivity即可了,而不必建立和初始化Application,由於一個應用從新進程的建立到進程的銷毀,Application僅僅會初始化一次。
App的啟動過程
本文所指的最佳化針對冷啟動。簡單解釋一下App的啟動過程:
1.點擊Launcher。啟動程式,通知ActivityManagerService
2.ActivityManagerService通知zygote進程孵化出應用進程,分配記憶體空間等
3.運行該應用ActivityThread的main()方法
4.代理程式更新ActivityManagerService它已經啟動,ActivityManagerService儲存一個該應用的代理對象,ActivityManagerService通過它能夠控制應用進程
5.ActivityManagerService通知應用進程建立入口的Activity執行個體,運行它的生命週期
啟動過程中Application和入口Activity的生命週期方法按例如以下順序調用:
1.Application 構造方法
2.attachBaseContext()
3.onCreate()
4.入口Activity的物件建構
5.setTheme() 設定主題等資訊
6.入口Activity的onCreate()
7.入口Activity的onStart()
8.入口Activity的onResume()
9.入口Activity的onAttachToWindow()
10.入口Activity的onWindowFocusChanged()
什麼才是應用的啟動時間
從點擊應用的啟動表徵圖開始建立出一個新的進程直到我們看到了介面的第一幀。這段時間就是應用的啟動時間。
我們要測量的也就是這段時間,測量這段時間能夠通過adb shell命令的方式進行測量,這樣的方法測量的最為精確,命令為:
adb shell am start -W [PackageName]/[PackageName.MainActivity]
1、ThisTime:一般和TotalTime時間一樣。除非在應用啟動時開了一個透明的Activity預先處理一些事再顯示出主Activity,這樣將比TotalTime小。
2、TotalTime:應用的啟動時間,包含建立進程+Application初始化+Activity初始化到介面顯示。
3、WaitTime:一般比TotalTime大點,包含系統影響的耗時。
利用TraceView分析啟動時間
在onCreate開始和結尾打上trace.
Debug.startMethodTracing("TestApp");...Debug.stopMethodTracing();
運行程式, 會在sdcard上產生一個”TestApp.trace”的檔案.
注意: 須要給程式加上寫儲存的許可權:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
通過adb pull將其匯出到本地
adb pull /sdcard/TestApp.trace ~/testSpeed.trace
開啟DDMS分析trace檔案,會出現下面的介面
一般僅僅須要關註:Calls + Recur Calls / Total和 Cpu Time / Call
Cpu Time / Call反映調用次數不多,但每次調用卻須要花費非常長時間的函數
Calls + Recur Calls / Total反映自身佔用時間不長,但調用卻非常頻繁的函數
怎樣降低應用啟動時的耗時
針對冷啟動時候的一些耗時。能夠採取下面策略:
1、在Application的構造器方法、attachBaseContext()、onCreate()方法中不要進行耗時操作的初始化,一些資料預取放在非同步線程中,能夠採取Callable實現。
2、對於sp的初始化,由於sp的特性在初始化時候會對資料所有讀出來存在記憶體中,所以這個初始化放在主線程中不合適,反而會延遲應用的啟動速度。對於這個還是須要放在非同步線程中處理。
3、對於MainActivity,由於在擷取到第一幀前。須要對contentView進行測量布局繪製操作,盡量降低布局的層次。考慮StubView的延遲載入策略,當然在onCreate、onStart、onResume方法中避免做耗時操作。
遵循上面三種策略可明顯提高app啟動速度。
最佳化應用啟動時的體驗
對於應用的啟動時間,僅僅能是盡量的避免一些耗時的、非必要的操作在主線程中。這樣相對能夠縮減一部分啟動的耗時。另外一方面在等待第一幀顯示的時間裡,能夠增加一些配置以增加體驗,比方增加Activity的background,這個背景會在顯示第一幀前提前顯示在介面上。 對於應用的啟動時間,僅僅能是盡量的避免一些耗時的、非必要的操作在主線程中,這樣相對能夠縮減一部分啟動的耗時,另外一方面在等待第一幀顯示的時間裡,能夠增加一些配置以增加體驗。比方增加Activity的background,這個背景會在顯示第一幀前提前顯示在介面上。
方案1:
1、先為主介面單獨寫一個主題style,設定一張待顯示的圖片,這裡我設定了一個顏色,然後在manifest中設定給MainActivity:
<style name="AppTheme.Launcher"> <item name="android:windowBackground">@drawable/bule</item></style>//... <activity android:name=".MainActivity" android:label="@string/app_name" android:theme="@style/AppTheme.Launcher"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
2、然後在MainActivity中載入布局前把AppTheme又一次設定給MainActivity:
@Override protected void onCreate(Bundle savedInstanceState) { setTheme(R.style.AppTheme); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);}
這樣在啟動時會先顯示background,然後待介面繪製完畢再顯示主介面:
方案2:通過設定Style
(1)設定背景圖Theme
通過設定一張背景圖。
當程式啟動時。首先顯示這張背景圖。避免出現黑屏
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="android:screenOrientation">portrait</item> <item name="android:windowBackground">>@mipmap/splash</item> <item name="android:windowIsTranslucent">true</item> <item name="android:windowNoTitle">true</item></style>
(2)設定透明Theme
通過把樣式設定為透明,程式啟動後不會黑屏而是整個透明了,等到介面初始化完才一次性顯示出來
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="android:windowNoTitle">true</item> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowIsTranslucent">true</item> <item name="android:screenOrientation">portrait</item> </style>
兩者對照:
Theme1 程式啟動快。介面先顯示背景圖,然後再重新整理其它介面控制項。給人重新整理不同步感覺。
Theme2 給人程式啟動慢感覺。介面一次性刷出來。重新整理同步。
(3)改動AndroidManifest.xml
<application android:name=".App" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true"> <activity android:name=".MainActivity" android:theme="@style/AppTheme"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> //......</application>
參考文獻:
http://www.jianshu.com/p/a0e242d57360
Android效能最佳化系列之App啟動最佳化