Android优化应用启动速度

一、应用的启动

启动方式

通常来说,在安卓中应用的启动方式分为两种:冷启动和热启动。

  • 1、冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动。
  • 2、热启动:当启动应用时,后台已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动应用,这个方式叫热启动。

特点

1、冷启动:冷启动因为系统会重新创建一个新的进程分配给它,所以会先创建和初始化Application类,再创建和初始化MainActivity类(包括一系列的测量、布局、绘制),最后显示在界面上。

2、热启动:热启动因为会从已有的进程中来启动,所以热启动就不会走Application这步了,而是直接走MainActivity(包括一系列的测量、布局、绘制),所以热启动的过程只需要创建和初始化一个MainActivity就行了,而不必创建和初始化Application,因为一个应用从新进程的创建到进程的销毁,Application只会初始化一次。

上面说的启动是点击app的启动图标来启动的,而另外一种方式是进入最近使用的列表界面来启动应用,这种不应该叫启动,应该叫恢复。

二、应用启动的流程

在安卓系统上,应用在没有进程的情况下,应用的启动都是这样一个流程:当点击app的启动图标时,安卓系统会从Zygote进程中fork创建出一个新的进程分配给该应用,之后会依次创建和初始化Application类、创建MainActivity类、加载主题样式Theme中的windowBackground等属性设置给MainActivity以及配置Activity层级上的一些属性、再inflate布局、当onCreate/onStart/onResume方法都走完了后最后才进行contentView的measure/layout/draw显示在界面上,所以直到这里,应用的第一次启动才算完成,这时候我们看到的界面也就是所说的第一帧。

所以,总结一下,应用的启动流程如下:

Application的构造器方法——>attachBaseContext()——>onCreate()——>Activity的构造方法——>onCreate()——>配置主题中背景等属性——>onStart()——>onResume()——>测量布局绘制显示在界面上。

三、测量应用启动的时间

在上面这个启动流程中,任何一个地方有耗时操作都会拖慢我们应用的启动速度,而应用启动时间是用毫秒度量的,对于毫秒级别的快慢度量我们还是需要去精确的测量到到底应用启动花了多少时间,而根据这个时间来做衡量。

什么才是应用的启动时间

从点击应用的启动图标开始创建出一个新的进程直到我们看到了界面的第一帧,这段时间就是应用的启动时间。

我们要测量的也就是这段时间,测量这段时间可以通过adb shell命令的方式进行测量,这种方法测量的最为精确,命令为:

adb shell am start -W [packageName]/[packageName.MainActivity]

执行成功后将返回三个测量到的时间:
1、ThisTime:一般和TotalTime时间一样,除非在应用启动时开了一个透明的Activity预先处理一些事再显示出主Activity,这样将比TotalTime小。
2、TotalTime:应用的启动时间,包括创建进程+Application初始化+Activity初始化到界面显示。
3、WaitTime:一般比TotalTime大点,包括系统影响的耗时。

下面是测量一个应用冷启动和热启动的时间:
冷启动:

热启动:

可以看到在进程已经存在的情况下,只需要重新初始化MainActivity,这样的启动比较快,不过大多数情况下应用的启动都是冷启动,因为用户都会在任务列表中手动关闭遗留的应用进程。

四、减少应用启动时的耗时

针对冷启动时候的一些耗时,如上测得这个应用算是中型的app,在冷启动的时候耗时已经快700ms了,如果项目再大点在Application中配置了更多的初始化操作,这样将可能达到1s,这样每次启动都明显感觉延迟,所以在进行应用初始化的时候采取以下策略:

  • 1、在Application的构造器方法、attachBaseContext()、onCreate()方法中不要进行耗时操作的初始化,一些数据预取放在异步线程中,可以采取Callable实现。
  • 2、对于sp的初始化,因为sp的特性在初始化时候会对数据全部读出来存在内存中,所以这个初始化放在主线程中不合适,反而会延迟应用的启动速度,对于这个还是需要放在异步线程中处理。
  • 3、对于MainActivity,由于在获取到第一帧前,需要对contentView进行测量布局绘制操作,尽量减少布局的层次,考虑StubView的延迟加载策略,当然在onCreate、onStart、onResume方法中避免做耗时操作。

遵循上面三种策略可明显提高app启动速度。

优化应用启动时的体验

对于应用的启动时间,只能是尽量的避免一些耗时的、非必要的操作在主线程中,这样相对可以缩减一部分启动的耗时,另外一方面在等待第一帧显示的时间里,可以加入一些配置以增加体验,比如加入Activity的background,这个背景会在显示第一帧前提前显示在界面上。
1、先为主界面单独写一个主题style,设置一张待显示的图片,这里我设置了一个颜色,然后在manifest中设置给MainActivity:

<style name="AppTheme.Launcher">
 <item name="android:windowBackground">@drawable/bule</item>
</style>
//...
  <activity
   android:name=".MainActivity"
   android:label="@string/app_name"
   android:theme="@style/AppTheme.Launcher">
   <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
   </intent-filter>
  </activity>

2、然后在MainActivity中加载布局前把AppTheme重新设置给MainActivity:

@Override
 protected void onCreate(Bundle savedInstanceState) {

  setTheme(R.style.AppTheme);
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
}

这样在启动时会先显示background,然后待界面绘制完成再显示主界面:

以上就是本文的全部内容,希望对大家学习Android软件编程有所帮助。

(0)

相关推荐

  • Android启动引导页使用ViewPager实现

    我们在安装某个APP的时候,基本都会有一个引导页的提示,他们可以打广告,或者介绍新功能的加入和使用说明等. 一般都支持滑动并且下面有几个点,显示共有多少页和当前图片的位置,在IOS上这个实现起来比较简单,但在安卓上如何实现呢. 今天就和大家一起来学习用官方v4支持包下的ViewPager来实现这个效果. 先上图: 下面是我的实现,一个xml布局,一个GuideActivity和一个GuidePageAdapter.  先上XML. <?xml version="1.0" enco

  • Android启动画面的实现方法

    本文实例讲述了Android启动画面的实现方法.分享给大家供大家参考.具体分析如下: 在应用程序中经常用到启动画面,会启动一个后台线程为主程序的运行准备资源. Android要实现启动画面可以这样做: 这是splash.xml布局文件的代码: 复制代码 代码如下: <LinearLayout   xmlns:android="http://schemas.android.com/apk/res/android"   android:layout_height="fill

  • Android编程之简单启动画面实现方法

    本文实例讲述了Android简单启动画面实现方法.分享给大家供大家参考,具体如下: 每个Android应用程序启动之后都会出现一个Splash启动界面,显示产品LOGO.公司LOGO或者开发者信息.如果应用程序启动时间比较长,那么启动界面就是一个很好的东西,可以让用户耐心等待这段枯燥的时间,提高用户体验. 1. splash.xml布局文件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android&q

  • Android 避免APP启动闪黑屏的解决办法(Theme和Style)

    前几天Boss就反应说,机器每次启动程序都会闪一下黑屏,这个客户不接受.没办法,只能想想怎么解决,最后找到了下面的方法.闪黑屏的原因主要是我们启动Activity的时候,需要跑完onCreate和onResume才会显示界面.也就是说需要处理一些数据后,才会显示.按照这种思路,是不是我把初始化的工作尽量减少就可以避免黑屏?事实是,就算你onCreate啥都不做,仍然会闪一下黑屏,因为初始化解析界面时需要一定时间.下面是解决办法:1.自定义Theme 复制代码 代码如下: 设置背景图Theme<s

  • Android软件启动动画及动画结束后跳转的实现方法

    本文实例讲述了Android软件启动动画及动画结束后跳转的实现方法.分享给大家供大家参考,具体如下: 自己写了个小程序,软件启动时,先显示几张图片,每3秒显示一张,图片显示完跳转到首页 1. 图片轮播使用Gallery,用法很简单 GalleryAdapter adapter = new GalleryAdapter(this, mIds); mGallery.setAdapter(adapter); GalleryAdapter是自定义适配器 public class GalleryAdapt

  • 详解Android中App的启动界面Splash的编写方法

    一.Splash界面的作用 用来展现产品的Logo 应用程序初始化的操作 检查应用程序的版本 检查当前应用程序是否合法注册 二.界面的xml定义 写一个布局背景设置为产品的logo图片,再添加一个textview显示版本号. <TextView android:id="@+id/tv_splash_version" android:layout_width="wrap_content" android:layout_height="wrap_cont

  • Android仿荷包APP启动动画

    用荷包App的时候发现启动动画做的挺好玩的,于是便模仿实现了一下. gif效果图: animation.gif 实现思路: 仔细观察,可以看出动画的执行分为两个阶段: 第一阶段为硬币掉落. 第二阶段为钱包反弹. 布局xml文件如下: <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/an

  • Android app启动时黑屏或者白屏的原因及解决办法

    1.产生原因 其实显示黑屏或者白屏实属正常,这是因为还没加载到布局文件,就已经显示了window窗口背景,黑屏白屏就是window窗口背景. 示例: 2.解决办法 通过设置设置Style (1)设置背景图Theme 通过设置一张背景图. 当程序启动时,首先显示这张背景图,避免出现黑屏 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name=&qu

  • Android简单实现启动画面的方法

    本文实例讲述了Android简单实现启动画面的方法.分享给大家供大家参考,具体如下: 核心代码: package com.demo.app; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.os.Handler; public class SplashActivity extends Activity { private final int S

  • Android优化应用启动速度

    一.应用的启动 启动方式 通常来说,在安卓中应用的启动方式分为两种:冷启动和热启动. 1.冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动. 2.热启动:当启动应用时,后台已有该应用的进程(例:按back键.home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动应用,这个方式叫热启动. 特点 1.冷启动:冷启动因为系统会重新创建一个新的进程分配给它,

  • Android 分析实现性能优化之启动速度优化

    目录 启动方式 冷启动(启动优化目标) 热启动 温启动 启动流程中可优化的环节 检测工具 启动时间检测 Logcat Displayed adb 命令统计 CPU profile API level >= 26 API level < 26 StrictMode 严苛模式 优化点 黑白屏问题 本文主要探讨以下几个问题: 启动方式 启动流程中可优化的环节 检测工具 优化点 黑白屏问题 启动方式 应用有三种启动状态,每种状态都会影响应用向用户显示所需的时间:冷启动.温启动与热启动 冷启动(启动优化

  • Android优化提升应用启动速度及Splash页面的设计

    目录 1.启动分为两种方式 2.如何测量一个应用的启动时间 3.应用启动的流程 4.减少应用的启动时间的耗时 5.如何设计延迟加载DelayLoad 1.启动分为两种方式 1) 冷启动:当直接从桌面上直接启动,同时后台没有该进程的缓存,这个时候系统就需要重新创建一个新的进程并且分配各种资源. 2) 热启动:该app后台有该进程的缓存,这时候启动的进程就属于热启动. 热启动不需要重新分配进程,也不会Application了,直接走的就是app的入口Activity,这样速度就很快 2.如何测量一个

  • Android 优化Handler防止内存泄露

    Android 优化Handler防止内存泄露 Demo描述: Handler可能导致的内存泄露及其优化 1 关于常见的Handler的用法但是可能导致内存泄露 2 优化方式请参考BetterHandler和BetterRunnable的实现 package cc.cc; import java.lang.ref.WeakReference; import android.os.Bundle; import android.os.Handler; import android.os.Messag

  • 最新IDEA 2022基于JVM极致优化 IDEA启动速度的方法

    目录 IDEA 2022最新版基于 JVM极致优化 IDEA 启动速度 1. 引言 2. 开始 结语 IDEA 2022最新版基于 JVM极致优化 IDEA 启动速度 1. 引言 相信做 Java 开发的同学,对 IDEA 这个工具应该都不陌生,即使不使用 IDEA 做开发,那么对 Eclipse 这个工具应该也不会陌生,如果这两个都不用的同学,我就想弱弱问一句,您不会是在使用记事本吧? 上面除了那个记事本,我相信所有的同学都对 IDEA 或者说 Eclipse 这两个工具的打开速度深有印象吧.

  • Android实战APP启动速度优化

    APP启动速度非常重要,APP启动速度慢,可能会造成用户体验不良好,尤其是在最近用Android studio之后,如果长时间不打开app,启动速度就会特别的慢,下面我们一起探讨一下影响app启动速度的原因,以及解决方案. 检测启动时间 首先我们要知道app的启动时间,然后你也可以凭着感觉来,这里我教大家一个装逼的方法: adb shell am start -W [packageName]/[.MainActivity] 用adb命令可以检测启动时间,示例如下: ./adb shell am

  • Android优化之启动页去黑屏实现秒启动

    前言 还记得之前我们写了一篇文章,基于RxJava实现酷炫启动页,然而当我们点击桌面图标启动APP时,有时会闪一下黑色背景,有时黑色背景时间还比较长,哎呀,难看死了,这个怎么办捏,别方,我们今天就来看看启动页的优化. 一.消除启动时的黑屏 点击桌面launcher图标启动APP,闪现的黑色背景其实是出现在我们看到界面第一帧之前.那我们就要想办法让这个黑色的背景变成用户喜欢看到的画面或者让它透明化.有了思路方法也就粗现了,我们有下面两种方案: 自定义WelcomActivity的Theme 说白了

  • Android 优化之卡顿优化的实现

    Android 系统每隔 16ms 会发出 VSYNC 信号重绘界面(Activity).之所以是 16ms,是因为 Android 设定的刷新率是 60FPS(Frame Per Second),也就是每秒 60 帧的刷新率,约合 16ms 刷新一次. 这就意味着,我们需要在 16ms 内完成下一次要刷新的界面的相关运算,以便界面刷新更新. 假设我们更新屏幕的背景图片需要 24ms 来做这次运算,当系统在第一个 16ms 时刷新界面,由于运算还没有结束,无法绘出图片.当系统隔 16ms 再发一

  • Android 优化之app启动优化的实现

    App 启动方式 冷启动 App 没有启动过或 App 进程被杀,系统中不存在该 App 进程,此时启动即为冷启动.需要创建 App 进程,加载相关资源,启动 Main Thread,初始化首屏 Activity 等.在这个过程中,屏幕会显示一个空白的窗口(颜色基于主题),直至首屏 Activity 完全启动. 热启动 热启动意味着 App 进程只是处于后台,系统只是将其从后台带到前台展示给用户.类同与冷启动,在这个过程中,屏幕会显示一个空白的窗口(颜色基于主题),直至 activity 渲染完

  • Android 优化之存储优化的实现

    交换数据格式 Google 推出的 Protocal Buffers 是一种更轻便高效的存储结构,但消耗内存较大. FlatBuffers同样由 Google 推出,专注性能,适合移动端.占用存储比 Protocal 要大. SharePreferences 优化 当 SharedPreferences 文件还没有被加载到内存时,调用 getSharedPreferences 方法会初始化文件并读入内存,这容易导致 耗时更长. Editor 的 commit 或者 apply 方法的区别在于同步

随机推荐