Android性能優(yōu)化(一)統(tǒng)計啟動時間

在優(yōu)化之前首先得有一個量化的過程,不然很難知道我們的優(yōu)化有沒有結果,不能總是靠感覺,就像看大師炒菜,大師告訴你放適量的鹽一樣蛋疼。

工具選擇

知道了啟動和頁面渲染的時間我們還得去找具體的位置,要是順便能定位位置就好了 ,抱著這種心態(tài),一開始我就瞄準的第三方的開源庫,大概找了下有騰訊的# Matrix和360的# ArgusAPM。但看到GitHub上的上次更新時間,瞬間有種情況不是很樂觀的感覺。

image.png

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

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

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

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

matrix找不到.png

看了下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,估計就是忘了在對應的地方插代碼了

image.png

統(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)化空間了


image.png

統(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,"------------------------------------------------");
    }

}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容