Android性能优化系列之布局优化

Android性能优化系列之内存优化

Android性能优化系列之apk瘦身

应用的启动速度缓慢是我们在开发过程中常常会遇到的问题,比方启动缓慢导致的黑屏。白屏问题,本篇博客就将介绍App启动优化的相关知识。

应用的启动方式

通常来说,启动方式分为两种:冷启动和热启动。

1、冷启动:当启动应用时。后台没有该应用的进程。这时系统会又一次创建一个新的进程分配给该应用。这个启动方式就是冷启动。

冷启动由于系统会又一次创建一个新的进程分配给它。所以会先创建和初始化Application类,再创建和初始化MainActivity类(包含一系列的測量、布局、绘制),最后显示在界面上。

2、热启动:当启动应用时,后台已有该应用的进程(例:按back键、home键,应用尽管会退出,可是该应用的进程是依旧会保留在后台,可进入任务列表查看)。所以在已有进程的情况下,这样的启动会从已有的进程中来启动应用,这个方式叫热启动。热启动由于会从已有的进程中来启动,所以热启动就不会走Application这步了。而是直接走MainActivity(包含一系列的測量、布局、绘制),所以热启动的过程仅仅须要创建和初始化一个MainActivity即可了,而不必创建和初始化Application,由于一个应用从新进程的创建到进程的销毁,Application仅仅会初始化一次。

App的启动过程

本文所指的优化针对冷启动。简单解释一下App的启动过程:

1.点击Launcher。启动程序,通知ActivityManagerService

2.ActivityManagerService通知zygote进程孵化出应用进程,分配内存空间等

3.运行该应用ActivityThread的main()方法

4.应用程序通知ActivityManagerService它已经启动,ActivityManagerService保存一个该应用的代理对象,ActivityManagerService通过它能够控制应用进程

5.ActivityManagerService通知应用进程创建入口的Activity实例,运行它的生命周期

启动过程中Application和入口Activity的生命周期方法按例如以下顺序调用:

1.Application 构造方法

2.attachBaseContext()

3.onCreate()

4.入口Activity的对象构造

5.setTheme() 设置主题等信息

6.入口Activity的onCreate()

7.入口Activity的onStart()

8.入口Activity的onResume()

9.入口Activity的onAttachToWindow()

10.入口Activity的onWindowFocusChanged()

什么才是应用的启动时间

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

我们要測量的也就是这段时间,測量这段时间能够通过adb shell命令的方式进行測量,这样的方法測量的最为精确,命令为:

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

1、ThisTime:一般和TotalTime时间一样。除非在应用启动时开了一个透明的Activity预先处理一些事再显示出主Activity,这样将比TotalTime小。

2、TotalTime:应用的启动时间,包含创建进程+Application初始化+Activity初始化到界面显示。

3、WaitTime:一般比TotalTime大点,包含系统影响的耗时。

利用TraceView分析启动时间

在onCreate開始和结尾打上trace.

Debug.startMethodTracing("TestApp");
...
Debug.stopMethodTracing();

运行程序, 会在sdcard上生成一个”TestApp.trace”的文件.

注意: 须要给程序加上写存储的权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

通过adb pull将其导出到本地

adb pull /sdcard/TestApp.trace ~/testSpeed.trace

打开DDMS分析trace文件,会出现下面的界面

一般仅仅须要关注:Calls + Recur Calls / Total和 Cpu Time / Call

Cpu Time / Call反映调用次数不多,但每次调用却须要花费非常长时间的函数

Calls + Recur Calls / Total反映自身占用时间不长,但调用却非常频繁的函数

怎样降低应用启动时的耗时

针对冷启动时候的一些耗时。能够採取下面策略:

1、在Application的构造器方法、attachBaseContext()、onCreate()方法中不要进行耗时操作的初始化,一些数据预取放在异步线程中,能够採取Callable实现。

2、对于sp的初始化,由于sp的特性在初始化时候会对数据所有读出来存在内存中,所以这个初始化放在主线程中不合适,反而会延迟应用的启动速度。对于这个还是须要放在异步线程中处理。

3、对于MainActivity,由于在获取到第一帧前。须要对contentView进行測量布局绘制操作,尽量降低布局的层次。考虑StubView的延迟载入策略,当然在onCreate、onStart、onResume方法中避免做耗时操作。

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

优化应用启动时的体验

对于应用的启动时间,仅仅能是尽量的避免一些耗时的、非必要的操作在主线程中。这样相对能够缩减一部分启动的耗时。另外一方面在等待第一帧显示的时间里,能够增加一些配置以增加体验,比方增加Activity的background,这个背景会在显示第一帧前提前显示在界面上。 对于应用的启动时间,仅仅能是尽量的避免一些耗时的、非必要的操作在主线程中,这样相对能够缩减一部分启动的耗时,另外一方面在等待第一帧显示的时间里,能够增加一些配置以增加体验。比方增加Activity的background,这个背景会在显示第一帧前提前显示在界面上。

方案1:

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,然后待界面绘制完毕再显示主界面:

方案2:通过设置Style

(1)设置背景图Theme

通过设置一张背景图。

当程序启动时。首先显示这张背景图。避免出现黑屏

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:screenOrientation">portrait</item>
<item name="android:windowBackground">>@mipmap/splash</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
</style>

(2)设置透明Theme

通过把样式设置为透明,程序启动后不会黑屏而是整个透明了,等到界面初始化完才一次性显示出来


<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:screenOrientation">portrait</item>
</style>

两者对照:

Theme1 程序启动快。界面先显示背景图,然后再刷新其它界面控件。给人刷新不同步感觉。

Theme2 给人程序启动慢感觉。界面一次性刷出来。刷新同步。

(3)改动AndroidManifest.xml

 <application
android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true">
<activity android:name=".MainActivity"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> //...... </application>

參考文献:

http://www.jianshu.com/p/a0e242d57360

Android性能优化系列之App启动优化的更多相关文章

  1. 一触即发 App启动优化最佳实践

    一触即发 App启动优化最佳实践 本文在 DiyCode 和 CSDN个人博客 同时首发,关注作者的 DiyCode帐号 或者 作者微博 可第一时间收到新文章推送. 文中的很多图都是Google性能优 ...

  2. JVM性能优化系列-(6) 晚期编译优化

    6. 晚期编译优化 晚期编译优化主要是在运行时做的一些优化手段. 6.1 JIT编译器 在部分的商用虚拟机中,java程序最初是通过解释器(Interpreter) 进行解释执行的,当虚拟机发现某个方 ...

  3. JVM性能优化系列-(5) 早期编译优化

    5. 早期编译优化 早起编译优化主要指编译期进行的优化. java的编译期可能指的以下三种: 前端编译器:将.java文件变成.class文件,例如Sun的Javac.Eclipse JDT中的增量式 ...

  4. 【转】Android总结篇系列:Activity启动模式(lauchMode)

    [转]Android总结篇系列:Activity启动模式(lauchMode) 本来想针对Activity中的启动模式写篇文章的,后来网上发现有人已经总结的相当好了,在此直接引用过来,并加上自己的一些 ...

  5. SQL优化系列(二)- 优化Top SQL

    优化最耗资源的N条SQL语句 如何从SGA或者AWR中找出最消耗资源的SQL, 例如最慢的20条SQL, 然后逐条优化? SQL自动优化工具SQL Tuning Expert Pro for Orac ...

  6. SQL优化系列(一)- 优化SQL

     优化SQL SQL开发人员从源代码中发现一条跑得很慢的SQL, 如何优化? DBA从AWR报告中发现一条跑得很慢的SQL,没有源代码或者不想修改源代码怎么办? SQL自动优化工具SQL Tuning ...

  7. Android性能优化-App启动优化

    原文地址:https://developer.android.com/topic/performance/launch-time.html#common 通常用户期望app响应和加载速度越快越好.一个 ...

  8. 提升HTML5的性能体验系列之五 webview启动速度优化及事件顺序解析

    webview加载时有5个事件.触发顺序为loading.titleUpdate.rendering.rendered.loaded.webview开始载入页面时触发loading,载入过程中如果&l ...

  9. 性能优化系列三:JVM优化

    一.几个基本概念 GCRoots对象都有哪些 所有正在运行的线程的栈上的引用变量.所有的全局变量.所有ClassLoader... 1.System Class.2.JNI Local3.JNI Gl ...

随机推荐

  1. NSLineBreakMode 的区别

    typedef enum {     UILineBreakModeWordWrap = 0,     UILineBreakModeCharacterWrap,     UILineBreakMod ...

  2. springboot—spring aop 实现系统操作日志记录存储到数据库

    原文:https://www.jianshu.com/p/d0bbdf1974bd 采用方案: 使用spring 的 aop 技术切到自定义注解上,针对不同注解标志进行参数解析,记录日志 缺点是要针对 ...

  3. NSZombie 详解 -僵尸对象

    1.什么是僵尸对象? 简而言之,就是过度释放的对象. 2.僵尸对象有什么特点? 如果一个对象a被变成了僵尸对象,那么,在进行下面的判断时,a是会被系统当成一个对象来进行判断的.但是,如果你使用a进行其 ...

  4. 从零开始,运行一个android例子程序

    电脑上连个eclipse都没装,怎么玩android?一穷二白的你, 下面就跟随我,从零开始,一步一步操作,运行我们的第一个android应用程序.我一直相信,学习开发,只有在调试过程中学的是最快的. ...

  5. 架构:Hexagonal Architecture Guidelines for Rails(转载)

    原文地址:http://theaudaciouscodeexperiment.com/blog/2014/03/17/hexagonal-architecture-guidelines-for-rai ...

  6. ASP.NET MVC:@helper 不能调试

    ASP.NET MVC 的 @helper 不能设置断点,当然我们可以将逻辑移动到扩展方法中,这里介绍另外一种方式,使用:System.Diagnostics.Debug.WriteLine,编程旅途 ...

  7. PetaPoco:SkipTake 和 Page 中的 OrderBy 子句不支持 “[]” 的解决办法

    PetaPoco 的 SkipTake 和 Page 方法内部采用了内联视图,而内联视图是不支持 OrderBy 的,因此 PetaPoco 对传入的 SQL 进行分析,对 OrderBy 子句进行分 ...

  8. sql --- where concat

    // where cancat 函数 SELECT * from  users WHERE email != CONCAT(username, '', '@huan1234qiu.com');

  9. 用UIBezierPath数组对UIView进行镂空处理

    用UIBezierPath数组对UIView进行镂空处理 效果 源码 // // CutOutClearView.h // CutOutMaskView // // Created by YouXia ...

  10. float浮点数的四舍五入

    瑞生网http://www.rationmcu.com版权所有 前几天,有个小伙伴在做实验过程中,发现了一个奇怪的现象,这个现象就是… 他在用printf输出浮点数的时候,想把数据保留到小数点后的两位 ...