衡量Android应用启动时间

时间:2013-01-02 15:48:44

标签: android

衡量Android应用启动时间的最精确方法是什么?

启动时间是指2和3之间的差异:

  1. 应用程序进程未运行
  2. 用户点击启动器中的应用图标
  3. 主要活动已完全初始化
  4. 所以我基本上需要以某种方式从JVM启动并记录它以后的时间。

9 个答案:

答案 0 :(得分:9)

我要将您的问题解释为'我的应用启动时间是否足够快。我如何检查我已经做了我能做的一切?'

启动时间在很大程度上是错误的指标,因为它会因设备和ROM而异。我想你最感兴趣的是你的代码需要花费很长时间才能执行,以及什么可能会阻塞主线程。

我发现最有效的方法是在app start上使用Traceview,然后查看执行方法所需的时间以及主线程是否有任何空白。

开始跟踪:

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Debug.startMethodTracing("startup");
    }
}

停止追踪:

@Override
public void onViewCreated(final View view, final Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    Debug.stopMethodTracing();
}

收集完跟踪后,您应该可以看到任何对启动时间有重大影响的内容。在我的情况下,如下所示,UI线程中存在一个很大的差距,即被阻止。

main thread blocked

发现Crashlytics和Coremetrics都需要调用randomUUID(),然后调用线程并阻塞主线程。解决方案只是启动一个新线程来初始化Coremetrics代码。

这是我在测量启动时间时不会想到的,但它实际上加快了应用程序的“启动时间”几百毫秒

这是在为Coremetrics初始化分离一个单独的线程后的另一个快照:

main thread not blocked

答案 1 :(得分:8)

我知道我来不及回答,尽管如此,这恰恰回答了这个问题。

默认情况下,对于API版本19或更高版本,此信息会记录在Logcat上。

  

从Android 4.4(API级别19)开始,logcat包含一个包含名为Displayed的值的输出行。此值表示启动过程和完成在屏幕上绘制相应活动之间所经过的时间量。

     

ActivityManager:显示com.android.myexample / .StartupTiming:+ 3s534ms

关键是在正确的位置寻找 -

  

如果您正在从命令行或终端中跟踪logcat输出,则查找已用时间非常简单。要在Android Studio中查找已用时间,必须在logcat视图中禁用过滤器。禁用过滤器是必要的,因为系统服务器而不是应用程序本身服务于此日志。

摘录来自documentation

答案 2 :(得分:5)

以下面的方式检查adb shell。

adb shell
adb logcat -b events | grep am_activity_launch_time

[Output]
01-01 12:32:53.469 1236 1262 I am_activity_launch_time: 
    [0,205360373,com.sec.android.app.clockpackage/.ClockPackage,378,**378**,0]

Remarks:
Launch time for Clock is 378ms.

答案 3 :(得分:4)

将整个onCreate()方法包装在TimingLogger中。把它放在开头:

TimingLogger timings = new TimingLogger(TAG, "methodA");

最后:

timings.dumpToLog();

如果你想在某个中间步骤中减少时间,你可以timings.addSplit("name");来获得进入该步骤所需的时间。

答案 4 :(得分:1)

可以使用下一个代码实现时间跟踪:

覆盖您的Application

public class CustomApplication extends Application {
    public final static long APP_START_TIME = System.currentTimeMillis();

    /**
     * Do all other application stuff
     */
}

并向主Activity添加几行:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final View contentView = findViewById(android.R.id.content);
        contentView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                if (Build.VERSION.SDK_INT >= 16) {
                    contentView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                } else {
                    contentView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                }
                long launchTime = System.currentTimeMillis() - CustomApplication.APP_START_TIME;
                Log.e("TEST", "App launch time = " + launchTime);
            }
        });
    }
}

并且不要忘记在Manifest中定义自定义应用程序:

<application
    android:label="@string/app_name"
    android:name=".CustomApplication" >

</application>

重要:您必须在启动前终止应用程序,因为Application会存储跟踪初始时间的静态变量。

答案 5 :(得分:1)

使用SysTrace

此外,Trace类可用于使用

测量节
Trace.beginSection("name");
Trace.endSection();

YouTube video也是一个快速入门。

答案 6 :(得分:1)

我认为这已内置到Firebase Console中,现在性能良好 enter image description here enter image description here

答案 7 :(得分:0)

一种可能性是将时间保存在onCreate()方法的开头和onCreate() method的末尾,然后相互减去这些时间,以便花时间初始化应用程序。

答案 8 :(得分:0)

在android中显示启动时间的简单方法。

enter image description here

有时logcat输出中的Displayed行包含一个用于总时间的附加字段。例如:

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms (total +1m22s643ms)

在这种情况下,第一次测量仅针对首次绘制的活动

来源:Time to initial display