前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【Android 性能优化】应用启动优化 ( 启动白屏问题 | 应用启动时间测量 | 冷启动 | 热启动 | 应用启动时间计算源码分析 )

【Android 性能优化】应用启动优化 ( 启动白屏问题 | 应用启动时间测量 | 冷启动 | 热启动 | 应用启动时间计算源码分析 )

作者头像
韩曙亮
发布于 2023-03-27 13:39:03
发布于 2023-03-27 13:39:03
5.3K00
代码可运行
举报
运行总次数:0
代码可运行

文章目录

一、 APP 启动白屏 / 黑屏


1 . 问题描述 : Android 应用启动时 , 尤其是大型复杂的应用 , 经常出现几秒钟的白屏或黑屏 , 黑屏或白屏取决于主界面 Activity 的主题风格 ;

2 . 解决方案 : Android 应用启动时很多大型应用都会有一个几秒的倒计时 , 并配上动态广告 , 这并不是开发者想要放上去的 , 而是为了避免上述启动白屏导致用户体很差 ;

3 . 启动优化 : 这里的应用启动白屏 / 黑屏的时间 , 是可以通过优化解决的 , 如将

3

秒钟的启动白屏卡顿 , 优化为毫秒级 ;

二、 APP 启动速度测量


1. 通过 Logcat 日志查看应用启动时间

通过 Logcat 日志查看应用启动时间 : 该方法只适用于 Android 4.4 版本之后的手机 ;

① 使用工具 : 使用 Android Studio 中的 Logcat 日志查看工具 ;

② 过滤选项 : 设置过滤选项为 No Filters , 这是系统 ActivityTaskManager 打印的 , 不属于应用日志信息 ;

③ 关键字 : 使用 Display 关键字过滤 ;

④ 截取到的日志信息如下 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2020-06-20 08:44:09.821 1266-1305/? I/ActivityTaskManager: Displayed kim.hsl.recyclerview/.MainActivity: +334ms
2020-06-20 08:44:18.457 1266-1305/? I/ActivityTaskManager: Displayed 
com.google.android.permissioncontroller/com.android.packageinstaller.permission.ui.GrantPermissionsActivity: +315ms
2020-06-20 08:44:22.308 1266-1305/? I/ActivityTaskManager: Displayed kim.hsl.cckfa/.MainActivity: +311ms

⑤ 具体操作选项参考下面的截图 :

2. 通过 adb 命令查看界面启动时间

通过 adb 命令查看界面启动时间 :

① 命令格式 : adb shell am start -W 包名/完整 Activity 类名 ;

② 本次命令 : adb shell am start -W kim.hsl.rtmp/kim.hsl.rtmp.MainActivity , 其中 kim.hsl.rtmp 是包名 , kim.hsl.rtmp.MainActivity 是完整的类名 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Microsoft Windows [版本 10.0.18362.900]
(c) 2019 Microsoft Corporation。保留所有权利。

C:\Users\octop>adb shell am start -W kim.hsl.rtmp/kim.hsl.rtmp.MainActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] 
cmp=kim.hsl.rtmp/.MainActivity }
Status: ok
LaunchState: COLD
Activity: kim.hsl.rtmp/.MainActivity
TotalTime: 374
WaitTime: 376
Complete

C:\Users\octop>

③ 命名截图 : 下面的截图作为参考 ;

④ Activity 界面源码 : 上述启动类类对应 RTMP_Pusher 应用中的主界面 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package kim.hsl.rtmp;
public class MainActivity extends AppCompatActivity {
	//...
}

三、 APP 冷启动与热启动


热启动的速度要远高于冷启动 ;

1 . 冷启动 : 应用后台没有该应用 , 该应用所有资源都要重新加载 , 分配新的进程 , 初始化 Application , 初始化 Activity 界面 ; 下图中的 LanuchState 中显示了启动的模式 , 下图中显示的是冷启动 ;

2 . 热启动 : 按下 Home 键 , 应用进入后台 , 再次启动 , 应用由后台转到前台 , 这种启动称为热启动 ; 下图中的 LanuchState 中显示了启动的模式 , 下图中显示的是热启动 ;

四、 APP 启动时间计算


1 . 启动 Activity 命令 : adb shell am start -W 包名/完整 Activity 类名 ;

2 . 日志打印内容 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
C:\Users\octop>adb shell am start -W kim.hsl.rtmp/kim.hsl.rtmp.MainActivity
Starting: Intent { act=android.intent.action.MAIN 
cat=[android.intent.category.LAUNCHER] cmp=kim.hsl.rtmp/.MainActivity }
Status: ok
LaunchState: COLD
Activity: kim.hsl.rtmp/.MainActivity
TotalTime: 431
WaitTime: 433
Complete

C:\Users\octop>

3 . am 命令及源码 : 在上述命令中可以启动 Android 应用 Activity 界面 , 其中 am 命令是由 Am.java 程序编译出来的 , 其路径是 \frameworks\base\cmds\am\src\com\android\commands\am\Am.java ;

4 . 分析 Am.java 可执行文件 :

① 执行启动 Activity 相关逻辑 : 启动前后都记录了时间 , 整个启动过程就是通过这两个时间计算出来的 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
IActivityManager.WaitResult result = null;
int res;

// 记录开始时间
final long startTime = SystemClock.uptimeMillis();
if (mWaitOption) {
    // 启动 Activity 
    result = mAm.startActivityAndWait(null, null, intent, mimeType,
                null, null, 0, mStartFlags, profilerInfo, null, mUserId);
    res = result.result;
} else {
    res = mAm.startActivityAsUser(null, null, intent, mimeType,
            null, null, 0, mStartFlags, profilerInfo, null, mUserId);
}
// 记录结束时间
final long endTime = SystemClock.uptimeMillis();

② 打印启动时间相关源码 : IActivityManager.WaitResult 对象中封装了 thisTime , totalTime 等时间信息 ; 这些时间都是在启动过程中计算的 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if (mWaitOption && launched) {
    if (result == null) {
        result = new IActivityManager.WaitResult();
        result.who = intent.getComponent();
    }
    System.out.println("Status: " + (result.timeout ? "timeout" : "ok"));
    if (result.who != null) {
        System.out.println("Activity: " + result.who.flattenToShortString());
    }
    if (result.thisTime >= 0) {
        System.out.println("ThisTime: " + result.thisTime);
    }
    if (result.totalTime >= 0) {
        System.out.println("TotalTime: " + result.totalTime);
    }
    System.out.println("WaitTime: " + (endTime-startTime));
    System.out.println("Complete");
}

5 . 分析启动时间计算源码 :

① 计算启动时间源码 : APP 启动时间计算在 \frameworks\base\services\core\java\com\android\server\am\ActivityRecord.java 类中计算 ;

② 在 windowsDrawn 方法中调用 reportLaunchTimeLocked 计算时间 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void windowsDrawn() {
    synchronized(service) {
        if (displayStartTime != 0) {
        	// 该方法是入口方法
            reportLaunchTimeLocked(SystemClock.uptimeMillis());
        }
        mStackSupervisor.sendWaitingVisibleReportLocked(this);
        startTime = 0;
        finishLaunchTickingLocked();
        if (task != null) {
            task.hasBeenVisible = true;
        }
    }
}

③ 启动时间计算 : 可以看到在 reportLaunchTimeLocked 方法中 , 计算了 thisTime 和 totalTime 的时间值 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    private void reportLaunchTimeLocked(final long curTime) {
        final ActivityStack stack = task.stack;
        // 这里计算了 APP 启动时间
        final long thisTime = curTime - displayStartTime;
        final long totalTime = stack.mLaunchStartTime != 0
                ? (curTime - stack.mLaunchStartTime) : thisTime;
        if (ActivityManagerService.SHOW_ACTIVITY_START_TIME) {
            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching", 0);
            EventLog.writeEvent(EventLogTags.AM_ACTIVITY_LAUNCH_TIME,
                    userId, System.identityHashCode(this), shortComponentName,
                    thisTime, totalTime);
            StringBuilder sb = service.mStringBuilder;
            sb.setLength(0);
            sb.append("Displayed ");
            sb.append(shortComponentName);
            sb.append(": ");
            TimeUtils.formatDuration(thisTime, sb);
            if (thisTime != totalTime) {
                sb.append(" (total ");
                TimeUtils.formatDuration(totalTime, sb);
                sb.append(")");
            }
            Log.i(ActivityManagerService.TAG, sb.toString());
        }
        mStackSupervisor.reportActivityLaunchedLocked(false, this, thisTime, totalTime);
        if (totalTime > 0) {
            //service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime);
        }
        displayStartTime = 0;
        stack.mLaunchStartTime = 0;
    }

6 . APP 启动时间总结 :

① 开始时间 : 点击 APP 图标 , 该时间就是 Am.java 中记录的 startTime 开始时间 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 记录开始时间
final long startTime = SystemClock.uptimeMillis();

② 系统分配内存时间 : 之后 Android 系统会给 APP 分配内存 , 这段时间是无法进行优化的 , 用户无法控制 , 占用时间由系统控制 ;

③ 画面绘制完毕调用方法 : 当调用 ActivityRecord.java 中的 windowsDrawn 方法时 , 画面绘制完毕 , 此时会调用 reportLaunchTimeLocked 方法 , 传入当前时间 SystemClock.uptimeMillis() 作为参数 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        if (displayStartTime != 0) {
        	// 该方法是入口方法
            reportLaunchTimeLocked(SystemClock.uptimeMillis());
        }

④ 画面绘制时间 : 在 reportLaunchTimeLocked 方法中 , 计算 thisTime 时间 , curTime 是传入的 SystemClock.uptimeMillis() 参数 , 即当前时间 , displayStartTime 是画面开始绘制的时间 , thisTime 就是画面绘制时间 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
final ActivityStack stack = task.stack;
final long thisTime = curTime - displayStartTime;

⑤ 总时间计算 : 这里计算总时间时 , 需要根据当前是冷启动还是热启动进行不同的计算 , 如果是冷启动 , (curTime - stack.mLaunchStartTime) 时间是总时间 , thisTime 是热启动的启动总时间 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
final long totalTime = stack.mLaunchStartTime != 0
        ? (curTime - stack.mLaunchStartTime) : thisTime;
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-06-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Android 性能优化】应用启动优化 ( 启动优化项目 | 界面启动时间 | 启动优化项目 | 方法追踪 MethodTracing )
在 【Android 性能优化】应用启动优化 ( 启动白屏问题 | 应用启动时间测量 | 冷启动 | 热启动 | 应用启动时间计算源码分析 ) __ 四、 APP 启动时间计算 博客中简要介绍了相关的启动时间 ;
韩曙亮
2023/03/27
1.3K0
App Launch Time Measurement
关于应用启动时间测量的分析已经有不少不错的文章做了总结,下面是比较好的几篇: 1.Android性能优化典范-第6季 2.测量Activity 的启动时间 3.Activity到底是什么时候显示到屏幕上的呢
宅男潇涧
2018/08/01
1.1K0
App Launch Time Measurement
如何统计Android App启动时间
随着App的逻辑不断庞大,一不注意就会将耗时的操作放置在应用启动过程之中,导致应用启动速度越来越慢,用户体验也越来越差。优化启动速度是几乎所有大型App应用开发者需要考虑的问题。优化启动速度之前首先需要准确测量App启动时间,这样有利于我们更准确可量化地看出优化效果,也可以指导我们进行持续优化。
用户1269200
2018/12/13
2.8K0
如何统计Android App启动时间
【Android 性能优化】应用启动优化 ( 阶段总结 | Trace 文件分析及解决方案 | 源码分析梳理 | 设置主题的方案总结 ) ★
2 . 启动白屏的解决方案 : 设置图片背景 , 或透明背景 , 这是个权宜之计 , 并不能根本性解决启动慢的问题 , 只是让用户体验效果好一些 ;
韩曙亮
2023/03/27
8840
Android性能优化系列之App启动优化
应用的启动速度缓慢是我们在开发过程中经常会遇到的问题,比如启动缓慢导致的黑屏,白屏问题,本篇博客就将介绍App启动优化的相关知识。
老马的编程之旅
2022/06/22
7160
Android性能优化系列之App启动优化
Android 性能分析学习(启动速度优化)
启动速度是用户体验app的第一感官,所以如果APP卡顿的话,给用户的体验会非常的糟糕。 本文主要针对这点进行的分析学习以及记录。
艳龙
2021/12/16
9050
Android 性能分析学习(启动速度优化)
你想要的Android性能优化系列:启动优化 !
手机桌面点击一个应用,用户希望应用能 及时响应、快速加载。启动时间过长的应用可能会令用户失望。这种糟糕的体验可能会导致用户在 Play 商店针对您的应用给出很低的评分,甚至完全弃用您的应用。
胡飞洋
2020/07/23
1.7K0
【App测试】怎么测试启动时间?
何小伟
2016/12/23
6.2K1
【App测试】怎么测试启动时间?
Android性能优化(一)—— 启动优化,冷启动,热启动,温启动
App启动方式分三种:冷启动(cold start)、热启动(hot start)、温启动(warm start)
233333
2024/06/28
2800
Android性能优化(一)—— 启动优化,冷启动,热启动,温启动
你的 APP 为何启动那么慢?
可见冷启动的必要条件是该APP进程不存在,这就意味着系统需要创建进程,APP需要初始化。在这三种启动方式中,冷启动耗时最长,对于冷启动的优化也是最具挑战的。因此本文重点谈论的是对冷启动相关的优化。
刘盼
2019/05/08
1.9K0
你的 APP 为何启动那么慢?
Android 优化——启动优化
adb shell am start -W [应用报名]/[Activity的全路径名],得到三个时间值:
三流之路
2018/09/11
9640
❤️Android 性能优化之启动优化❤️
用户希望应用能够快速打开。启动时间过长的应用不能满足这个期望,并且可能会令用户失望。轻则鄙视你,重则直接卸载你的应用。
Android 帅次
2021/11/12
9210
❤️Android 性能优化之启动优化❤️
APP性能测试—启动耗时
应用启动是整个App工序的第一道流程。对于开发者,一般需要在应用启动过程中进行初始化工作,启动页的UI展示。而对于用户来说,启动速度的快慢则极大地影响了使用体验,并且间接地影响了用户的留存率。
清风穆云
2021/08/09
2.8K0
你必须要掌握的Android冷启动优化
事件发生在发包上线的前两天,在某某云进行移动测试时,提示冷启动速度低于平均值的问题,之前自己也曾尝试过优化,但是发现效果并不是很明显,作为一个有追求的开发者,趁着有点空闲时间,要好好研究一下冷启动优化问题。
用户1269200
2018/12/07
1.8K0
Android性能优化,一对一直播源码启动速度优化之耗时检测处理
一对一直播源码的启动速度缓慢这是很多开发者都遇到的一个问题,比如启动缓慢导致的黑屏,白屏问题,大部分的答案都是做一个透明的主题,或者是做一个Splash界面,但是这并没有从根本上解决这个问题。那么如何从根本上解决这个问题或者做到一定程度的缓解?
云豹科技程序员
2021/06/24
4980
测试应用启动性能
本文的编写目的,更多的在于介绍性能、启动测试以及我进行启动测试背后的原因。但如果您只是希望能够快速获得结论,可以直接参考下面的内容:
Android 开发者
2022/03/09
3850
深入研究Android启动速度优化(上)- 看完这些启动优化已经完成80%了
启动是指用户从点击 icon 到看到页面首帧的整个过程,启动优化的目标就是减少这一过程的耗时。启动性能是 APP 使用体验的门面,启动过程耗时较长很可能导致用户使用 APP 的兴趣骤减。提高启动速度是每一个 APP 在体验优化方向上必须要做的关键技术突破。
Rouse
2024/05/09
1.8K0
深入研究Android启动速度优化(上)- 看完这些启动优化已经完成80%了
【 Android 场景化性能测试】启动速度篇
本文主要介绍了如何通过抓包工具分析Android启动速度数据,包括使用Charles、Wireshark、Fiddler等工具,以及如何利用这些工具收集、分析数据,最后通过表格的形式直观地展示数据。
腾讯移动品质中心TMQ
2017/11/01
2.1K0
【 Android 场景化性能测试】启动速度篇
APP启动速度优化
APP启动速度非常重要,APP启动速度慢,可能会造成用户体验不良好,尤其是在最近用Android studio之后,如果长时间不打开app,启动速度就会特别的慢,下面我们一起探讨一下影响app启动速度的原因,以及解决方案。
haifeiWu
2018/09/11
7070
APP常见性能测试点之响应时间
  软件的响应时间和响应速度直接影响到用户的体验度,如果一个软件,迟迟加载不出来,会直接影响到软件的日活、留存。因此对于一个软件,对响应速度测试是必不可少的。
顾翔
2021/07/22
3K0
推荐阅读
相关推荐
【Android 性能优化】应用启动优化 ( 启动优化项目 | 界面启动时间 | 启动优化项目 | 方法追踪 MethodTracing )
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文