上關于這塊大部分教程都是無效的,因為墻的緣故,無法使用官方提供的下載鏈接,我這里使用了清華大學的鏡像,是能夠順利將 AOSP 下載下來。如果你還沒有安裝 Ubuntu,請看《VirtualBox 安裝 Ubuntu》。
Repo 是一款工具,可讓您在 Android 環境中更輕松地使用 Git,首先需要安裝 Git:
sudoapt-get install git
創建 bin,并加入 path:
mkdir~/bin PATH=~/bin:$PATH
下載 repo:
curlhttps://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo
錯誤:
Command 'curl'not found, but can be installed with: ? sudoapt install curl
需要安裝 curl,執行命令sudo apt-get install curl進行安裝。
注意:命令 apt 在低版本 Ubuntu 不行,本教程統一使用命令 apt-get。
權限設置:
chmoda+x ~/bin/repo
如何驗證 repo 安裝成功
輸入命令repo,提示:
/usr/bin/env: "python": 沒有那個文件或目錄
需要安裝 python,執行命令sudo apt-get install python安裝,再次輸入命令repo,提示如下即 repo 安裝成功:
error: repo is not installed. Use "repo init"to install it here.
初始化倉庫
建立工作目錄 AOSP,命令:
mkdir AOSP cd AOSP
初始化倉庫:
repo init -uhttps://aosp.tuna.tsinghua.edu.cn/platform/manifest
錯誤
錯誤1
error.GitError: manifests var: *** 請告訴我你是誰。 ? 運行 ? gitconfig --globaluser.email "you@example.com" gitconfig --globaluser.name "Your Name" ? 來設置您賬號的缺省身份標識。 如果僅在本倉庫設置身份標識,則省略 --global參數。
沒有設置身份,要使用 Gerrit 代碼審核工具,您需要一個與已注冊的 Google 帳號關聯的電子郵件地址:
gitconfig --globaluser.email "wuxiaolong.github.io@gmail.com" gitconfig --globaluser.name "WuXiaolong"
其他郵箱應該也是可以的。
錯誤2
fatal: Cannot gethttps://gerrit.googlesource.com/git-repo/clone.bundle fatal: error [Errno 101] Network is unreachable
因為 repo 運行過程中會嘗試訪問官方的 git 源更新自己,如果想使用 tuna 的鏡像源進行更新,將如下內容復制到你的~/.bashrc里,然后重啟終端模擬器。
exportREPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo/'
錯誤3:
curl: (22) The requested URL returned error: 404Not Found Server does not provide clone.bundle; ignoring.
為什么會出現此種 log ?
在通過 Git 的 HTTP 協議下載最新數據之前,Repo 嘗試下載預先打包的捆綁文件以引導每個 git。
原文:Repo attempts to download a prepackaged bundle file to bootstrap each git prior to downloading the most recent data via Git's HTTP protocol.
如果捆綁文件不可用(如本例所示),Repo 將忽略它并繼續進行,換句話說,不要注意這一點。
原文:If a bundle file isn't available (like in this case), Repo will ignore it and proceed anyway. In other words, don't pay any attention to this.
最后,如何取消 download clone.bundle ?
只需要 在repo 添加一個參數 --no-clone-bundle,如下:
可通過 repo <cmd> -h 獲得參數 --no-clone-bundle 的說明
repo init --no-clone-bundle repo sync --no-clone-bundle
指定某個 Android 版本
如果需要某個特定的 Android 版本(列表):
repo init -uhttps://aosp.tuna.tsinghua.edu.cn/platform/manifest -bandroid-8.0.0_r1
提示以下,即 init 成功:
Your identity is: WuXiaolong <wuxiaolong.github.io@gmail.com> If you want to change this, please re-run 'repo init'with --config-name ? repo has been initialized in/media/disk/Project/AOSP ?
疑問
如果沒有指定版本,如何知道下載好的 AOSP 是什么版本?
找到build/make/core/version_defaults.mk文件打開,搜索PLATFORM_SDK_VERSION,找到了 PLATFORM_SDK_VERSION :=28,從 SDK 版本可以知道 AOSP 版本是 9.0,我下載的就是最新的。
同步代碼
同步源碼樹(以后只需執行這條命令來同步):
repo sync
然后等待下載完畢:
正在檢出文件: 100% (1709/1709), 完成. 正在檢出文件: 100% (9492/9492), 完成.在檢出文件: 2% (251/9492) 正在檢出文件: 100% (617/617), 完成.正在檢出文件: 17% (106/617) 正在檢出文件: 100% (15779/15779), 完成.檢出文件: 7% (1251/15779) 正在檢出文件: 100% (29/29), 完成. 正在檢出文件: 27% (8/29) Syncing work tree: 100% (568/568), done.
最后整個源碼大小 27.2 G。
https://source.android.google.cn/setup/
點擊上方藍字關注公眾號
碼個蛋第233次推文
不是秒開算我輸
作者:r17171709
博客:http://www.jianshu.com/u/470afcb80dc2
文章目錄
App啟動方式
App啟動時間
系統提供的啟動時間方案
ADB命令提供的啟動時間方案
利用TraceView分析啟動時間
從Theme方向來優化加載時間
性能問題分析
你一定遇到過這種情況:點擊App圖標,先出現一個白屏或者黑屏頁面,然后過一會才進入主界面。這時候你會懵逼,這是什么呀?!這種用戶體驗是極度糟糕的。通過本篇文章,我們就會知道這個問題產生的原因以及如何避免這個問題的產生
0
App啟動方式
冷啟動:冷啟動指的是應用程序從無到有的啟動方式。在應用程序自設備啟動以來第一次啟動或系統殺死應用程序等情況下會發生冷啟動。這種類型的啟動在最小化啟動時間方面的挑戰是最大的,因為系統和應用程序比其他啟動狀態有更多的工作要做。
來看看應用程序冷啟動的整體流程
application以及activity初始化是一個相當復雜的過程,而白屏或者黑屏恰恰就是這個過程的產物:在應用程序剛啟動到應用程序初始化完全之間有一段時間空隙,這時候系統創建了一個空白窗口,叫StartingWindow。這個窗口讓人感覺activity已經啟動了只是沒填充好數據。它是個臨時窗口,對應的WindowType是TYPE_APPLICATION_STARTING。這個空白窗口是為了告訴用戶,系統已經接受到操作,正在響應。應用程序初始化完成加載完第一幀之后,這個窗口就會被移除。
Window的頂層是DecorView,所以StartingWindow顯示一個空DecorView,但是會給這個DecorView應用當前activity指定的Theme,如果這個activity沒有指定Theme就用application的。activity啟動時,windowBackground比setContentView要先加載,這一段時間如果Theme是Light,屏幕就是白色的;如果是Dark,就會顯示黑屏。
上述就是黑白屏的原因了
熱啟動:熱啟動要比冷啟動簡單得多,開銷也更低。熱啟動下,系統只是把你的activtiy帶到前臺而已。如果應用程序中所有的activtiy仍然留存在內存中,那么就可以避免重復初始化對象還有繪制和渲染布局。但如果內存緊張造成應用程序被回收,那這些工作依然要重新執行。熱啟動與冷啟動有著相同的屏幕顯示行為:系統進程在直到應用程序完成渲染activity為止之前會一直顯示一個空白窗口,即StartingWindow。
溫啟動:
用戶退出你的App,然后又重新啟動它。這個過程可能會讓應用程序繼續執行,但是需要重新創建activity。
1
App啟動時間
為了對App啟動性能進行正確的評估,啟動時間這一指標就顯得尤為重要。App的啟動時間指的是從點擊應用的啟動圖標開始到我們看到了界面的第一幀這段時間
系統提供的啟動時間方案
自Android 4.4之后,logcat新增一個輸出,關鍵字叫Displayed,這個關鍵字可以粗略的提現App啟動時間
ADB命令提供的啟動時間方案
我們來運行一下這個命令看看效果
可以看到這里有三個時間參數ThisTime、TotalTime、WaitTime,簡單介紹一下這三個參數:
ThisTime:一連串啟動的activity中的最后一個activity的啟動耗時
TotalTime:新進程和Activity的啟動耗時,但不包括前一個應用activity中pause方法的耗時
WaitTime:總的耗時,包括前一個應用activity中pause方法的耗時和新應用啟動的時間
一般情況下TotalTime跟ThisTime的值是相同的。有一個場景會導致這2個值不相等,比如點擊App圖標,先啟動一個無界面的activity做邏輯處理,接著又啟動一個有界面的activity
在第①個時間段內,AMS創建ActivityRecord記錄塊和選擇合理的Task、將當前resume的activity進行pause
在第②個時間段內,啟動進程、調用無界面activity的onCreate等、 pause/finish無界面的activity
在第③個時間段內,調用有界面activity的onCreate、onResume
需要注意的是這些時間值雖然每次都不一樣,也談不上絕對的正確,但是他們之間的差別不會太大,還是能夠說明一些問題的
2
利用TraceView分析啟動時間
TraceView是什么,TraceView是Android平臺特有的數據采集和分析工具,主要用做熱點分析,找出最需要優化的點。TraceView從代碼層面分析性能問題,針對每個方法來分析,比如當我們發現自己的App出現卡頓的時候,可以用它來分析出現卡頓時在方法中有沒有很耗時的操作。
通過TraceView,可以得到兩組很重要的數據:
單次執行最耗時的方法
執行次數最多的方法
采集數據的方式有兩種,
第一種是通過代碼來得到traceview文件,你可以直接在需要統計的代碼部分頭尾設置,比如我這里是統計application中的onCreate方法
生成的traceview文件會自動放在SDCARD上,沒有SDCARD卡會出現異常,所以使用這種方式需要確保應用的AndroidMainfest.xml中的SD卡的讀寫權限是打開的,其中aizuna.trace是traceview文件的名字,然后用adb導出traceview文件。
traceview文件
使用Android Device Monitor打開traceview
第二種同樣是使用Android Device Monitor
先選擇應用進程,然后點擊Start Method Profiling(開啟方法分析),按鈕會變為Stop Method Profiling(停止方法分析),開啟方法分析后,對應用的目標頁面進行測試操作,測試完畢后停止方法分析,界面會自動跳轉到DDMS的trace分析界面。
兩種方式的對比:第一種方式更精確到方法,起點和終點都是自己定,不方便的地方是自己需要添加方法并且要導出文件,第二種方式的優缺點剛好相反。
開發者最關心的數據主要是:
Calls + Recur Calls / Total:調用次數+遞歸次數,一般用來查找自身占用時間不長,但調用卻非常頻繁的方法
Cpu Time / Call:某個函數消耗CPU的平均時間,一般用來查找調用次數不多,但每次調用卻需要花費很長時間的方法
耗時超過500ms都是值得注意的
點擊每個方法, 可以看到其父方法(調用它的)和它的所有子方法(它調用的),同時上方的該方法執行時間軸會閃動,顯示為該方法的執行線程及相對時長
現在來看看我的項目中application啟動耗時
大多數都是集中在第三方庫,比如阿里熱修復、Fresco
3
從Theme方向來優化加載時間
我們都希望自己App在啟動加載過程中與加載完成之后的主題效果接近,而不是很突兀的將這個緩慢的過程被系統直接展示出來
有一個較通用的做法就是直接使用windowDisablePreview。windowDisablePreview就是禁用窗口的預覽動畫。在SplashActivity顯示出來之前,系統永遠不會使用該Activtiy的主題來顯示加載過程,這樣就保證了不會出現白屏或者黑屏現象。但是,與設置windowIsTranslucent屬性一樣,如果啟動過程中有過多復雜的操作,就會出現過了好幾秒才展現App,會給用戶造成App沒有正常運行的錯覺,微信貌似就是這種體驗
谷歌建議不要使用此種方法,而是建議遵循Material Design,在主題上使用windowBackground屬性為SplashActivity提供一個簡單的自定義Drawable
先創建一個drawable
隨后運用到style上
最后配置在AndroidManifest上
如果你想過渡到App本身的主題,只需要在super.onCreate方法和setContentVIew方法之前調用setTheme(R.style.AppTheme)即可
這里簡單介紹下其中陌生的屬性:
android:opacity=”opaque”是為了防止在啟動的時候出現背景的閃爍
layer-list你可以自行百度一下相關的文檔,不是很復雜
4
性能問題分析
上面的做法可以達到"秒開"APP的效果,不過卻不是真正提升App啟動的速度。真正優化這些問題還需對application和activity進行下手。
這里給出幾點建議:
1、很多第三方SDK都放在application初始化,我們可以將初始化的代碼放到使用到的地方再進行相關操作,比如科大訊飛、百度地圖這種SDK
2、SplashActivity中的布局盡量減少復雜性以及布局深度,因為在View繪制的過程中,測量也是很耗費性能的。也可以采用ViewStub的形式進行懶加載優化
3、不要在這兩處方法中進行耗時操作。這些I/O操作也應該放到使用到的地方或子線程中執行。
4、對于多進程的應用來說,每新建一個進程就會初始化application一次,這樣會造成application的onCreate方法執行多次,所以需要考慮哪些初始化操作只要執行1次
5、Multidex的使用,也是拖慢啟動速度的元兇,必須要做優化。
不過有些時候真的沒辦法去去除這些初始化的功能,比如Fresco,比如熱修復,所以我們也只能盡量的做上述這些事情