在優(yōu)化之前首先得有一個量化的過程,不然很難知道我們的優(yōu)化有沒有結果,不能總是靠感覺,就像看大師炒菜,大師告訴你放適量的鹽一樣蛋疼。
工具選擇
知道了啟動和頁面渲染的時間我們還得去找具體的位置,要是順便能定位位置就好了 ,抱著這種心態(tài),一開始我就瞄準的第三方的開源庫,大概找了下有騰訊的# Matrix和360的# ArgusAPM。但看到GitHub上的上次更新時間,瞬間有種情況不是很樂觀的感覺。

尤其是360這個,去年開源,上次更新就是9月前,跟不維護差不多了,再去issue里看看,情況真的不容樂觀:

瞬間感覺自己攤上大事了,我還只是個孩紙啊,行吧,我們再去看看騰訊大哥的Matrix吧

大哥就是大哥,那還等啥,擼吧。
一頓操作猛如虎,一看BUG有2個痛點
1.沒辦法像Matrix的demo那樣統(tǒng)計啟動之類的時間,因為工程用的是AndroidX

2.每次修改類都需要clean一次工程,這個很耗時間啊

看了下issue,發(fā)現(xiàn)不少反饋這樣的問題,都沒有得到官方正式的回復,哎,好難,沒辦法只能自己搞了。
自己寫簡陋版時間統(tǒng)計
自己搞雖然沒有Matrix這樣可以很快的定位到問題,但也是有自己的優(yōu)勢的,比如編譯快。加入Matrix的Trace模塊可以明顯感受到編譯慢了很多要1m18s,而正常調試編譯的時候只需要38s左右,這是因為編譯期間trace模塊會會自動在每個方法是開始和結束加入時間統(tǒng)計的標識,這樣方便我們定位問題。
主要統(tǒng)計的就是application創(chuàng)建時間、啟動頁(Splash)時間、第一個Activity渲染完成的時間。
最近負責項目的啟動順序
application初始化一些庫=》Splash(一個)=》MainActivity(FirstActivity)
當前Activity加載完成的標志是參考Matrix里的代碼,發(fā)現(xiàn)在Activity的onWindowFocusChange()里面有特別的插樁代碼,源碼里的注釋也證實了觀點,之所以不支持AndroidX,估計就是忘了在對應的地方插代碼了

統(tǒng)計Activity頁面加載時間
因為有BaseActivity,所以從這著手,在onCreate時記錄,在第一次獲得焦點時結束,統(tǒng)計時間差,大概就是Activity的頁面加載時間了
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
timeOnCreate = System.currentTimeMillis();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (isFirstFocus && hasFocus){
TraceHelper.get().onWindowFocusChange(tag,System.currentTimeMillis()-timeOnCreate);
isFirstFocus=false;
}
}
統(tǒng)計一次冷啟動時間
application創(chuàng)建時間=splashOnCreate()-start()
Splash渲染時間=onWindowFocusChange()-onCreate()
Splash停留的時間=mainActivityOnCreate()-splashOnCreate()
MainActivity渲染時間=onWindowFocusChange()-onCreate()
冷啟動時間=MainActivityonWindowFocusChange()-applicationOnCreate()
自己項目的統(tǒng)計效果:測試機器Redmi5(驍龍450+3gRAM),缺少了Splash的頁面渲染時間,而我在oncreat方法里面就設置了跳轉,推測是這樣沒有獲得焦點,MainActivity有3秒,有很大優(yōu)化空間了

統(tǒng)計方法時間
通過上面的過程,我們得到了一個總體的時間,我們想細化定位的話還得知道這個過程里方法執(zhí)行的時間,由于方法數(shù)比較多,而且方法統(tǒng)計在整個項目都有用到的地方,肯定就不能再像上面那樣自己寫了,由于時間緊我還沒有找到一個合適的第三方庫,只能等Matrix修復或者你們有更好的也可以在評論里分享一下
最后附上本次的工具類:
/**
* create by z on 19/12/27
*
* @author z
*/
public class TraceHelper {
private boolean isEnable = true;
private static TraceHelper instance;
private long startTime;
private long splashOnCreateTime;
private long mainActivityTime;
private long completeTime;
private Map<String,Long> activityRenderTimes=new HashMap<>();
private TraceHelper() {
}
public static TraceHelper get() {
if (instance == null) {
synchronized (TraceHelper.class) {
if (instance == null) {
instance = new TraceHelper();
}
}
}
return instance;
}
private long getTime(){
return System.currentTimeMillis();
}
public void start() {
startTime = getTime();
}
public void splashOnCreate() {
splashOnCreateTime = getTime();
}
public void mainActivity(){
mainActivityTime = getTime();
}
@SuppressLint("DefaultLocale")
public void onWindowFocusChange(String tag, long timeMist) {
Log4jUtils.d(this,String.format("onWindowFocusChange--tag[%s]-----time[%d]",tag,timeMist));
activityRenderTimes.put(tag,timeMist);
//冷啟動時間
if (tag.contains("MainActivity")){
complete();
}
}
private void complete(){
if (isEnable){
completeTime=getTime();
show();
}
}
public void show(){
Log4jUtils.d(this,"------------------------------------------------");
Log4jUtils.d(this,"--applicationCreateTime: "+(splashOnCreateTime-startTime));
Log4jUtils.d(this,"--SplashStayTime: "+(mainActivityTime -splashOnCreateTime));
Log4jUtils.d(this,"--completeTime: "+(completeTime-startTime));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
activityRenderTimes.forEach((s, aLong) -> {
Log4jUtils.d(this,"--"+s+": "+aLong);
});
}
Log4jUtils.d(this,"------------------------------------------------");
}
}