浅谈android性能优化之启动过程(冷启动和热启动)
本文介绍了浅谈android性能优化之启动过程(冷启动和热启动) ,分享给大家,具体如下:
一、应用的启动方式
通常来说,启动方式分为两种:冷启动和热启动。
1、冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动。
2、热启动:当启动应用时,后台已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动应用,这个方式叫热启动。
特点
1、冷启动:冷启动因为系统会重新创建一个新的进程分配给它,所以会先创建和初始化application类,再创建和初始化mainactivity类(包括一系列的测量、布局、绘制),最后显示在界面上。
2、热启动:热启动因为会从已有的进程中来启动,所以热启动就不会走application这步了,而是直接走mainactivity(包括一系列的测量、布局、绘制),所以热启动的过程只需要创建和初始化一个mainactivity就行了,而不必创建和初始化application,
因为一个应用从新进程的创建到进程的销毁,application只会初始化一次。
二、应用的启动过程
冷启动启动流程:当点击app的启动图标时,安卓系统会从zygote进程中fork创建出一个新的进程分配给该应用,之后会依次创建和初始化application类、创建mainactivity类、加载主题样式theme中的
windowbackground等属性设置给mainactivity以及配置activity层级上的一些属性、再inflate布局、当oncreate/onstart/onresume方法都走完了后最后才进行contentview的measure/layout/draw显示在界面上,所以直到这里,
应用的第一次启动才算完成,这时候我们看到的界面也就是所说的第一帧。所以,总结一下,应用的启动流程如下:
application的构造器方法——>attachbasecontext()——>oncreate()——>activity的构造方法——>oncreate()——>配置主题中背景等属性——>onstart()——>onresume()——>测量布局绘制显示在界面上。
大致流程如下:
1、点击桌面图标,launcher会启动程序默认的acticity,之后再按照程序的逻辑启动各种activity
2、启动activity都需要借助应用程序框架层的activitymanagerservice服务进程(service也是由activitymanagerservice进程来启动的);在android应用程序框架层中,activitymanagerservice是一个非常重要的接口,
它不但负责启动activity和service,还负责管理activity和service。
step 1. 无论是通过launcher来启动activity,还是通过activity内部调用startactivity接口来启动新的activity,都通过binder进程间通信进入到activitymanagerservice进程中,并且调用activitymanagerservice.startactivity接口;
step 2. activitymanagerservice调用activitystack.startactivitymaywait来做准备要启动的activity的相关信息;
step 3. activitystack通知applicationthread要进行activity启动调度了,这里的applicationthread代表的是调用activitymanagerservice.startactivity接口的进程,对于通过点击应用程序图标的情景来说,这个进程就是launcher了,
而对于通过在activity内部调用startactivity的情景来说,这个进程就是这个activity所在的进程了;
step 4. applicationthread不执行真正的启动操作,它通过调用activitymanagerservice.activitypaused接口进入到activitymanagerservice进程中,看看是否需要创建新的进程来启动activity;
step 5. 对于通过点击应用程序图标来启动activity的情景来说,activitymanagerservice在这一步中,会调用startprocesslocked来创建一个新的进程,而对于通过在activity内部调用startactivity来启动新的activity来说,这一步是不需要执行的,
因为新的activity就在原来的activity所在的进程中进行启动;
step 6. activitymanagerservic调用applicationthread.schedulelaunchactivity接口,通知相应的进程执行启动activity的操作;
step 7. applicationthread把这个启动activity的操作转发给activitythread,activitythread通过classloader导入相应的activity类,然后把它启动起来。
三、冷启动过程中碰到的白屏黑屏以及优化启动时间
1、白屏问题 :
android studio升级 2.0之后 加上instant run,instant run为了能够让我们快速部署代码,背后其实是有一套非常复杂的逻辑的,比如要在apk中建立服务器与android studio进行通信,以及代码差异比对和替换等,在研发过程中可能出现白屏问题,
一般release版的程序是不会出现这种现象的;
如果接下来还会出现白屏问题,可以查看style文件
<style name="apptheme" parent="theme.appcompat.light.darkactionbar"> ...... <item name="android:windowistranslucent">true</item> <item name="android:windownotitle">true</item> </style>
加入了两个属性,windowistranslucent和windownotitle,将这两个属性都设置成true,就可以让程序在初始化的时候窗口是透明的,初始化结束后程序主界面才会显示出来,从而也就完全看不到白屏界面了
2、启动时间的优化
先测量activity的启动时间-------activity的reportfullydrawn()方法
你就需要调用activity的reportfullydrawn()。它将在log里报告从apk初始化(和前面displayed的时间是一样的)到reportfullydrawn() 方法被调用用了多长时间。
reportfullydrawn()方法显示的log也是类似这样:
activitymanager: displayed com.android.myexample/.startuptiming: +768ms
在4.4上调用reportfullydrawn()方法会崩溃(但是log还是能正常打印),提示需要update_device_stats权限 ,但是这个权限只有系统app才能授权。解决的办法是这样调
try{ reportfullydrawn(); }catch(securityexception e){ }
还有一种测量启动时间的方法也值得一提,那就是screenrecord命令
首先启动带—bugreport选项(它可以在frames 中添加时间戳-应该是l中的特性)的screenrecord 命令:
$ adb shell screenrecord --bugreport /sdcard/launch.mp4
然后点击app的图标,等待app显示,ctrl-c screenrecord, 使用adb pull命令把文件导出到电脑。
$ adb pull /sdcard/launch.mp4
现在你可以打开录制视频看看发生了什么。你需要一个能逐帧查看的视频播放器(mac上的quicktime 就可以,不清楚其它os上什么播放器这个功能最好使)。现在逐帧播放,注意视频的上方有一个frame 时间戳。
一直往前直到你发现app图标高亮了为止。这个时候系统已经处理了图标上的点击事件,开始启动app了,记录下这一帧的时间。继续播放帧直到你看到了app整个ui的第一帧为止。根据不同情况(是否有启动窗口,是否有启动画面等等),
事件和窗口发生的实际顺序可能会有不同。对于一个简单的app来说,你会首先见到启动窗口,然后渐变出app真实的ui。在你看到ui上的任何内容之后,你应该记录下第一帧,这时app完成了布局和绘制,准备开始显示出来了。同时也记录下这一帧所发生的时间。
现在把这两个时间相减 ((ui displayed) - (icon tapped)); 得到app从点击到绘制就绪的所有时间。虽然这个时间包含了进程启动之前的时间,但是至少它可以用于跟其他app比较。
android冷启动时间优化
冷启动时间是指当用户点击你的app那一刻到系统调用activity.oncreate()之间的时间段。在这个时间段内,windowmanager会先加载app主题样式中的windowbackground做为app的预览元素,然后再真正去加载activity的layout布局
冷启动时间优化
知道了android冷启动时间的原理之后,就可以通过一些小技巧来对冷启动时间进行优化,从而让你app加载变得”快“一些(视觉体验上的快)。我们可制作一个启动activity的背景样式的.9图片,然后把这个.9图片做为windowbackground。
图片制作好之后,我们就可以用它做为app冷启动阶段的预览元素,如下设置:
为启动的activity自定义一个theme
<style name="apptheme.launcher"> <item name="android:windowbackground">@drawable/window_background_statusbar_toolbar_tab</item> </style>
将新的theme应用到设置到androidmanifest.xml中
<activity android:name=".mainactivity" android:theme="@style/apptheme.launcher"> <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity>
由于给mainactivity设置了一个新的theme,这样做会覆盖原来的theme,所以在mainactivity中需要设置回原来的theme
public class mainactivity extends appcompatactivity { @override protected void oncreate(bundle savedinstancestate) { // make sure this line comes before calling super.oncreate(). settheme(r.style.apptheme); super.oncreate(savedinstancestate); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。