Launcher到Application.attachBaseContext的时间统计

112 阅读2分钟

当被问到Launcher到Application.attachBaseContext这段时间的时长怎么统计? 是否脑子嗡嗡的? 只听说过,APP的启动耗时?却没听说过上面的这个问题。如果是问APP的启动 耗时那简单:APP启动后,在logcat中过滤Displayed关键字,即可看到自己的APP启动 耗时了。或者adb shell am start -W 包名/.Activity 这种方式去启动APP也能看到启动耗时。

image.png

这可把我难住了...... 首先Displayed的时长统计和adb shell am start -W的统计输出是一样的。它们统计到Activity 的onWindowFocusChanged结束,那我是不是可以在Application的attachBaseContext记录 当前时间,到Activity.onWindowFocusChanged的时候减去attachBaseContext记录的时间, 那就得到了除Launcher到Application.attachBaseContext的时间了?我感觉这样是可以的,但是 并不严谨,应该Displayed统计的时长并不是从Launcher的startActivity开始的。 如果我们能在Launcher的startActivity前记录一下当前时间,然后到启动App进入到 Application.attachBaseContext时减去那个记录的时间,就完美得到了Launcher到attachBaseContext 的时间统计了。但是问题是Launcher的startActivity我们无法插入记录当前时间的代码呢? 解决上面的办法我想到了一个:我们自己写一个新的app,里面就只有一个功能就是startActivity, 专门去启动目标Activity,那样我们就能在startActivity前记录当前时间了。再在启动目标app后, 取出那个记录的时间,就能统计launcher到Application.attachBaseContext的时间了,完美。

下面贴出例子代码: 启动目标Activity的App代码:

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemProperties;
import android.view.View;

/**
 * 用于启动目标Activity
 */
public class ToStartActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.icon).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SystemProperties.set("starttime", String.valueOf(System.currentTimeMillis()));
                Intent intent1 = new Intent();
                intent1.setAction("android.intent.action.super");
                intent1.addCategory("android.intent.category.DEFAULT");
                intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent1);
            }
        });
    }
}

上面是一个app。

下面是目标app的Application代码:


import android.app.Application;
import android.content.Context;
import android.os.Handler;
import android.os.MessageQueue;
import android.os.SystemProperties;
import android.util.Log;

public class MyApplication extends Application {
    private long startTime = 0;
    private Handler handler = new Handler();

    @Override
    protected void attachBaseContext(Context base) {
        startTime = System.currentTimeMillis();
        handler.getLooper().getQueue().addIdleHandler(new MessageQueue.IdleHandler() {
            @Override
            public boolean queueIdle() {
                long startTime2 = SystemProperties.getLong("starttime", 0);
                Log.d("MyApplication", "launcher到application.attaBaseContext的时间==" + (startTime - startTime2));
                return false;
            }
        });
        super.attachBaseContext(base);
    }
}

个人感觉这个时间统计并没有什么用,只能证明Displayed的时间统计不是从Launcher的startActivity开始的。