美文网首页
Android性能优化:启动优化

Android性能优化:启动优化

作者: tianyl | 来源:发表于2019-02-10 17:08 被阅读0次

索引

Android中的App启动,是从用户点击应用图标的那一刻起,到应用界面显示出来的过程。这段过程有的应用耗时少,有的应用则耗时多,如果我们想要对那些耗时多的应用进行优化。那么,首先我们需要知道从应用图标被点击,到界面加载出来发生了什么。然后,我们需要知道这段过程中为什么会发生部分耗时长的操作,最后,我们需要知道如何优化一款App的启动速度

目录

  1. 应用图标被点击到界面加载出来的过程
  2. 启动中出现的问题及其原因
  3. 常用的启动优化手段

1. App的启动过程

1.1 App的点击时的启动逻辑

首先,我们要知道Android系统的桌面就是一个应用,我们的应用图标在桌面上的那个界面其实就是一个Activity,当我们的应用图标被点击时,就触发了这个Activity的点击事件

位于com.android.launcher2包下

public final class Launcher extends Activity

当点击Activity界面上的一个item(也就是一款应用的icon)的时候,会调用它的onClick方法

public void onClick(View v) {

    if (v.getWindowToken() == null) {
        return;
    }
    if (!mWorkspace.isFinishedSwitchingState()) {
        return;
    }
    Object tag = v.getTag();
    if (tag instanceof ShortcutInfo) {
        ...
        //这里是启动Activity
        boolean success = startActivitySafely(v, intent, tag);
        if (success && v instanceof BubbleTextView) {
            mWaitingForResume = (BubbleTextView) v;
            mWaitingForResume.setStayPressed(true);
        }
    } ...
}

上面代码较多,所以省去其他的逻辑,只需要看到其中一行调用startActivitySafely,就是启动Activity

boolean startActivitySafely(View v, Intent intent, Object tag) {
    boolean success = false;
    try {
        success = startActivity(v, intent, tag);
    } catch (ActivityNotFoundException e) {
        Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
        Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
    }
    return success;
}
//从startActivitySafely调用而来的
boolean startActivity(View v, Intent intent, Object tag) {
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    try {

        boolean useLaunchAnimation = (v != null) &&
                !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);
        UserHandle user = (UserHandle) intent.getParcelableExtra(ApplicationInfo.EXTRA_PROFILE);
        LauncherApps launcherApps = (LauncherApps)
                this.getSystemService(Context.LAUNCHER_APPS_SERVICE);
        if (useLaunchAnimation) {
            ...
        } else {
            if (user == null || user.equals(android.os.Process.myUserHandle())) {
                //这里是真正启动Activity的代码
                startActivity(intent);
            } else {
                launcherApps.startMainActivity(intent.getComponent(), user,
                        intent.getSourceBounds(), null);
            }
        }
        return true;
    } catch (SecurityException e) {
       ...
    }
    return false;
}

从startActivitySafely到startActivity,最终会调用到Activity中的startActivity(intent)方法,这个方法就和平时启动Activity是一样的

1.2 startActivity的调用步骤

  1. 这时的startActivity会开启一个新的app
  2. 首先会加载一个main函数,并分配一些内存区域(包括方法区,堆区和java栈)
  3. java栈中会调用到ActivityThread中的main函数,实例化一个Application
  4. 调用Application的onCreate方法
  5. 开启MainActivity

2 启动中出现的问题及其原因

2.1 启动白屏

白屏:是由于AppCompat的主题属性:windowBackgroud导致的,他是一个白色的背景

3 启动优化手段

3.1 启动速度

通过Display这个关键字,就可以在log里获取到系统打印的启动时间

3.1.1 启动速度测试

adb shell am start -W 包名/全类名
参考对比:QQ
adb shell am start -W com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity
启动时就会有时间
调用这句命令时,会走到这个方法

//AM.java
result = mAm.startActivityAndWait(null, null, intent, mimeType,
null, null, 0, mStartFlags, profilerInfo, null, mUserId);
//返回的result里面,就有时间信息

3.2.1 启动速度相关时间

WaitTime

startTime记录的刚准备调用startActivityAndWait()的时间点
endTime记录的是startActivityAndWait()函数调用返回的时间点
WaitTime = startActivityAndWait()调用耗时。

ThisTime和TotalTime

解释下代码里curTime、displayStartTime、mLaunchStartTime三个时间变量.
curTime表示该函数调用的时间点.
displayStartTime表示一连串启动Activity中的最后一个Activity的启动时间点.
mLaunchStartTime表示一连串启动Activity中第一个Activity的启动时间点

正常情况下点击桌面图标只启动一个有界面的 Activity,此时 displayStartTime 与mLaunchStartTime 便指向同一时间点,此时 ThisTime=TotalTime。另一种情况是点击桌面图标应用会先启动一个无界面的 Activity 做逻辑处理,接着又启动一个有界面的Activity,在这种启动一连串 Activity 的情况下(知乎的启动就是属于这种情况),displayStartTime 便指向最后一个 Activity 的开始启动时间点,mLaunchStartTime 指向第一个无界面Activity的开始启动时间点,此时 ThisTime!=TotalTime。

一个应用 Activity pause 的耗时。也就是说,开发者一般只要关心 TotalTime 即可,这个时间才是自己应用真正启动的耗时。
最后总结一下,如果只关心某个应用自身启动耗时,参考TotalTime;如果关心系统启动应用耗时,参考WaitTime;如果关心应用有界面Activity启动耗时,参考ThisTime

ThisTime、TotalTime 的计算在 frameworks\base\services\core\java\com\android\server\am\ActivityRecord.java 文件的 reportLaunchTimeLocked() 函数中

3.2 主题优化(简单)

给splash界面设置主题。例如app启动时启动的是AActivity,那么就给AActivity设置一个单独的主题Launch
然后在AActivity的onCreate方法中,在super.onCreate之前,将主题还原

<!--APP的基础主题-->
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
<!--APP的启动时使用的主题-->
<style name="LaunchTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="android:windowBackground">@drawable/bg</item>
</style>

然后在第一个显示的activity中,将主题替换回来

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState)
    Thread.sleep(2000)//do something
    setTheme(R.style.AppTheme);
    setContentView(R.layout.activity_main)
}

这样使用,就可以避免app在启动时,耗时过长导致的白屏问题。当然,也可以不使用特定的背景,而使用透明背景,也是可行的。例如

<!--APP的启动时使用的主题-->
<style name="LaunchTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="android:windowIsTranslucent">true</item>
</style>

3.3 trace文件优化

File file = new File(Environment.getExternalStorageDirectory(), "app7");
Debug.startMethodTracing(file.getAbsolutePath());
//执行方法
Debug.stopMethodTracing()

通过startMethodTracing方法可以获取trace文件,来分析方法执行的时机和次数
对于那些耗时较长的方法,可以通过以下几种方式优化
1、子线程
2、懒加载
对于那些耗时特别长的方法,可以具体分析,优化代码

总结

到此,App启动也基本总结完了,最好还是那一句,良好的代码习惯才是最重要的

注:此文属作者原创,转载请标明出处

相关文章

  • 收集_性能优化

    Android性能优化(一)之启动加速35%Android性能优化(二)之布局优化面面观Android性能优化(三...

  • Android性能优化--内存优化

    转载自:Android性能优化--内存优化 上一篇文章关于Android性能优化--启动优化探讨了启动优化相关的知...

  • Android系统原理

    Android性能优化(一)App启动原理分析及启动时间优化 - CSDN博客 Android性能优化(二)布局渲...

  • Android性能优化之路

    Android性能优化目录 1 Android性能优化之内存泄漏2 Android性能优化之启动速度3 Andro...

  • 性能问题_01参考文章

    参考文章 : Android性能优化(一)之启动加速35% Android性能优化(二)之布局优化面面观 Andr...

  • Android性能优化之启动速度优化

    Android性能优化之启动速度优化 Android app 启动速度优化,首先谈谈为什么会走到优化这一步,如果一...

  • Android 性能优化

    app性能优化 android优化分为: 内存优化 UI优化 电量优化 apk瘦身优化 启动优化 下面通过各种百度...

  • Android性能优化(下)

    Android性能优化 内存泄漏和性能优化方式Android性能优化(上)数据库优化和网络优化Android性能优...

  • Android优化文章精选

    Android性能优化典范 Android性能优化典范 - 第1季Android性能优化之渲染篇Android性能...

  • [笔记]Android性能优化 中

    [笔记]Android性能优化 上[笔记]Android性能优化 中[笔记]Android性能优化 下 7.And...

网友评论

      本文标题:Android性能优化:启动优化

      本文链接:https://www.haomeiwen.com/subject/zxjllqtx.html