Android性能优化(一)—— 启动优化,冷启动,热启动,温启动

Android性能优化(一)—— 启动优化,冷启动,热启动,温启动标签 Android 架构师之路 APP 启动方式 App 启动方式分三种 冷启动 coldstart 热启动 hotstart 温启动 warmstart 冷启动系统不存在 App 进程 APP 首次

大家好,欢迎来到IT知识分享网。

标签 : Android架构师之路


APP启动方式

App启动方式分三种:冷启动(cold start)、热启动(hot start)、温启动(warm start)

冷启动

第一阶段

第二阶段

系统一旦创建了app进程,app进程就要负责做以下的任务:

热启动

温启动

温启动包含了冷启动的一些操作,由于app进程依然在,温启动只执行冷启动的第二阶段,这代表着它比热启动有更多的开销。

温启动有很多场景,例如:

  • 用户按连续按返回退出了app,然后重新启动app;
  • 由于系统收回了app的内存,然后重新启动app。

App启动优化

app启动优化的方向是冷启动。

空白window问题

app启动时,会短暂的一瞬间白屏:

冷启动动画
这个动图是我在Application的oncCreate里线程休眠1s实现。虽然如此,但是实际项目中确实存在启动时白屏时间过长的问题。

要看怎么解决,先问为什么会有白屏

在上面讲冷启动第一阶段,启动app之后,立即展示一个空白的window,那么具体怎么展示,为什么要展示空白的window呢?

我们看app启动流程加载首屏部分源码:

ActivityStack

 // Set to false to disable the preview that is shown while a new activity // is being started. private static final boolean SHOW_APP_STARTING_PREVIEW = true; void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity, boolean newTask, boolean keepCurTransition, ActivityOptions options) { 
      //…… 省略一万行…… if (!isHomeOrRecentsStack() || numActivities() > 0) { 
      if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare open transition: starting " + r); //…… 省略一万行…… boolean doShow = true; if (newTask) { 
      // Even though this activity is starting fresh, we still need // to reset it to make sure we apply affinities to move any // existing activities from other tasks in to it. // If the caller has requested that the target task be // reset, then do so. if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) { 
      resetTaskIfNeededLocked(r, r); doShow = topRunningNonDelayedActivityLocked(null) == r; } } else if (options != null && options.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) { 
      doShow = false; } if (r.mLaunchTaskBehind) { 
      // Don't do a starting window for mLaunchTaskBehind. More importantly make sure we // tell WindowManager that r is visible even though it is at the back of the stack. r.setVisibility(true); ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); // 如果同时满足,则显示空白屏幕 } else if (SHOW_APP_STARTING_PREVIEW && doShow) { 
      //…… //显示空白屏幕 r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity)); } } else { 
      // If this is the first activity, don't do any fancy animations, // because there is nothing for it to animate on top of. ActivityOptions.abort(options); } } 

这里省略了部分代码,只保留关键代码。

显示白屏由两个变量决定:SHOW_APP_STARTING_PREVIEW,在activity启动前时否显示预览;doShow,其默认值为true,但是它由newTask决定,是否为一个全新的activity栈,也就是说,SHOW_APP_STARTING_PREVIEW为true,并且app冷启动,就显示白屏。

那么,能不能不显示白屏呢?

  • 禁用app启动时window预览的功能

在主题中为首屏activity添加一个注意,禁用window预览的功能,并在manifest中使用

<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> <!--禁用预览功能主题--> <style name="AppSpalshNoPreviewTheme" parent="AppTheme"> <item name="android:windowFullscreen">true</item> <item name="windowNoTitle">true</item> <!-- <item name="android:windowContentOverlay">@null</item>--> <!-- <item name="android:windowBackground">@mipmap/wall</item>--> <item name="android:windowDisablePreview">true</item> </style> </resources> 
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.margin.myapplication"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:name=".MyApplication" android:theme="@style/AppTheme" tools:ignore="GoogleAppIndexingWarning"> <activity android:name=".SplashActivity" android:theme="@style/AppSpalshNoPreviewTheme"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".HomeActivity" android:launchMode="singleTask"/> </application> </manifest> 

在网上看到说可以将首屏背景设为透明背景,就是我注释掉的两行,但是实际测试发现会透明,但是会出现黑屏的问题,估计这种也不靠谱还麻烦,所以直接忽略它,直接禁用预览功能。

效果如下:

禁止预览

言归正传,这种方式虽然可以帅锅给系统,并且之前支付宝好像竟然这么干过!但是并不是好的办法,接下来,我们往下看另一种方法。

  • 给空白首屏Activity设置一个背景

在style.xml中给SplashActivity添加一个新主题,设置一个背景:

 <!--替换首屏的背景的主题--> <style name="AppSpalshBackgroundTheme" parent="AppTheme"> <item name="android:windowBackground">@mipmap/wall</item> <item name="android:windowFullscreen">true</item> <item name="windowNoTitle">true</item> </style> 

效果如下:

设置首屏背景

从源头解决

上面两种方式,看似挺不错,尤其是第二种,效果竟然看着还不错??😂😂😂

但是!上面的方式治标不治本只是障眼法,我们还是要从根源上解决问题!

从上面冷启动的介绍可知,app启动过程中,会有如下几个重要过程:

Created with Raphaël 2.3.0 load and launch App showPreviewWindow init app init splashActivity replace previewWindow with splashActivity

所以,要想解决白屏的问题,就要减少白屏显示的时间!也就是说要加快app初始化首屏绘制的时间

像上面,我实现长时间白屏,就是在application的onCreate方法中,让线程休眠一段时间:

public class MyApplication extends Application { 
      @Override public void onCreate() { 
      super.onCreate(); try { 
      Thread.sleep(1500); } catch (InterruptedException e) { 
      e.printStackTrace(); } } } 

看到这段代码,是不是让你产生了一些思路呢?

  • 减少Application 初始化的工作量。

我们通常会在Application的onCreate方法中可以做一些轻量化的初始化操作。当onCreate任务越多耗时操作越多,初始化越慢,于是splashActivity启动时间就越晚,白屏时间就越长咯。

一些三方的SDK,文件,设备,线程池,等等工具类,等等尽可能不要在application中初始化。

  • 加快UI绘制
    其实这个已经是老生常谈的话题了,常常由一下几种方案:
  1. 减少布局嵌套层级。
    布局层级越深,执行measure,layout次数就越多越耗时,ui绘制自然就越慢。我曾经见过一位大神,一个xml嵌套8-9层甚至十几层!我始终想不明白大神到底是计算机专业的还是护理专业的。

此刻我不得不说约束布局——ConstraintLayout是真的香!只要你用的好,布局合理,甚至可以零嵌套!

  1. 减少布局元素
    布局中元素越多,单帧UI绘制就越耗时,所以尽可能减少布局元素。事实上,不管是首屏还是其他的activity或者fragment布局都应该尽可能的减少布局元素。注意有时候可能为了方便,布局中放了一些不可见或占位的控件,应该减少这种情况,因为他们也参与绘制过程的。
    另外还可以使用viewStub标签,使用时再初始化需要的布局,非常方便。

  2. 避免过度绘制
    减少不必要的背景设置。
    尽可能避免元素重叠。既设置了背景又重叠,就会有不必要的耗时绘制。
    还是要减少不必要的站位元素。



APP性能优化不仅仅时启动优化,还有很多内容,比如布局优化(这里包含了部分)、数据结构优化、网络优化、线程优化,业务逻辑优化、内存优化、资源优化、apk瘦身等等等等很多,还有很多性能优化工具这里没有提及,现在先给自己挖个坑,以后有时间补上把😂😂😂

深夜写的有些匆忙着急,如果有不足之处还望多多包涵并欢迎批评指正,非常感谢😜😜😜

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/137431.html

(0)
上一篇 2025-06-20 17:20
下一篇 2025-06-20 17:26

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信