# Android APP性能优化--白屏启动速度优化

# Android APP性能优化–白屏启动速度优化

一、界面优化

设置启动activity主题,背景设置为图片或背景色一致的颜色值。启动速度未改变,视觉上不再有白屏。代码如下:

1.style文件添加主题(主主题,动画主题,启动页主题)
   <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <!-- 隐藏状态栏 -->
        <item name="android:windowFullscreen">true</item>
        <!-- 隐藏标题栏 -->
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowAnimationStyle">@style/noAnimation</item>
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
    
    <style name="noAnimation">
        <item name="android:activityOpenEnterAnimation">@null</item>
        <item name="android:activityOpenExitAnimation">@null</item>
        <item name="android:activityCloseEnterAnimation">@null</item>
        <item name="android:activityCloseExitAnimation">@null</item>
        <item name="android:taskOpenEnterAnimation">@null</item>
        <item name="android:taskOpenExitAnimation">@null</item>
        <item name="android:taskCloseEnterAnimation">@null</item>
        <item name="android:taskCloseExitAnimation">@null</item>
        <item name="android:taskToFrontEnterAnimation">@null</item>
        <item name="android:taskToFrontExitAnimation">@null</item>
        <item name="android:taskToBackEnterAnimation">@null</item>
        <item name="android:taskToBackExitAnimation">@null</item>

    </style>
    
    <style name="LaunchTheme" parent="AppTheme">
    <item name="android:windowBackground">@drawable/splash_layer</item>
    <item name="android:windowFullscreen">true</item>
    </style>
    
2.修改mainfest中启动activity的主题为上述LaunchTheme
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.why.project.androidstartingwindowdemo">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <!--将首页的them设置成自定义的样式-->
        <activity
            android:name="MainActivity"
            android:screenOrientation="landscape"
            android:theme="@style/LaunchTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
                <category android:name="android.intent.category.HOME.PEITE" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>

</manifest>

二、App启动分类

1.冷启动 Cold start

在启动应用前,系统还没有App的任何进程。比如设备开机后应用的第一次启动,系统杀掉应用进程 (如:系统内存吃紧引发的 kill 和 用户主动产生的 kill) 后 的再次启动等。那么自然这种方式下,应用的启动时间最长。

2.热启动 Warm start

当应用中的 Activities 被销毁,但在内存中常驻时,应用的启动方式就会变为暖启动。相比冷启动,暖启动过程减少了对象初始化、UI的布局和渲染。启动时间更短。但启动时,系统依然会展示一个空白背景,直到第一个 Activity 的内容呈现为止。

3.温启动 Lukewarm start

用户退出您的应用,但随后重新启动。该过程可能已继续运行,但应用程序必须通过调用onCreate()从头开始重新创建活动。系统从内存中驱逐您的应用程序,然后用户重新启动它。进程和Activity需要重新启动,但任务可以从保存的实例状态包传递到onCreate()中。

启动速度优化主要是针对冷启动方式

三、启动时间获取&分析

获取App启动时间的几种方法:

1.adb命令获取
adb shell am start -S -R 5 -W 包名/完整的Activity名

这个命令的输出日志如下:

Stopping: 包名
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=包名/完整的Activity名 }
Status: ok
Activity: 包名/完整的Activity名
ThisTime: 2808
TotalTime: 2808
WaitTime: 2832

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

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

**WaitTime:**一般比TotalTime大点,包括系统影响的耗时。

2.用TraceView分析启动时间
打开方式:

TraceView 位于 Android Devices Monitor 里面。可以在 Android Studio ——>Tools ——>moniter 中找到 Android Devices Monitor。在 Monitor 中就可以打开对应的 Trace 文件,或者进行 Trace 操作。

分析启动时间

1.在application或者mainActivity的onCreate的始末位置添加打印trace语句(“”中为trace文件的文件名):

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

2.App启动运行后,会在sd卡中生成SysTime.trace文件,或者手机Android——>data——>"包名"路径下,用moniter打开,可以进行分析

分析面板含义:
名字含义
Incl Cpu TimeCpu执行该方法该方法及其子方法所花费的时间
Name方法的详细信息,包括包名和参数信息
Incl Cpu Time %Cpu执行该方法该方法及其子方法所花费占Cpu总执行时间的百分比
Excl Cpu TimeCpu执行该方法所话费的时间
Excl Cpu Time %Cpu执行该方法所话费的时间占Cpu总时间的百分比
Incl Real Time该方法及其子方法执行所话费的实际时间,从执行该方法到结束一共花了多少时间
Incl Real Time %上述时间占总的运行时间的百分比Incl Real Time %
Excl Real Time %该方法自身的实际允许时间
Excl Real Time上述时间占总的允许时间的百分比
Calls+Recur调用次数+递归次数,只在方法中显示,在子展开后的父类和子类方法这一栏被下面的数据代替
Calls/Total调用次数和总次数的占比
Cpu Time/CallCpu执行时间和调用次数的百分比,代表该函数消耗cpu的平均时间
Real Time/Call实际时间于调用次数的百分比,该表该函数平均执行时间

分析面板截图如下:按照耗时时间长短排列,点击可查看父类函数中各子类耗时长短,根据耗时针对性进行优化。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ijOi45Rg-1572172419637)(C:\Users\IvyZhao\Desktop\Image_20191009194240.png)]

四、优化方案

1.避免application中onCreat进行太多初始化

Application里面的初始化操作不结束,其他任意的程序操作都无法进行。Application的onCreate中会做大量第三方组件的初始化工作,其实很多组件是需要做区别对待的,有些可以做延迟加载,有些可以放到其他的地方做初始化操作,特别需要留意包含Disk IO操作,网络访问等严重耗时的任务,他们会严重阻塞程序的启动。

实现方法:

-异步加载、延时加载、懒加载

-判断第三方库初始化能否在子线程中加载

-项目是多进程架构,只在主进程执行Application的onCreate();

2.MainActivity的onCreate避免执行过多初始化

2.1使用延迟加载。

确保在Activity的页面显示出来之后再进行加载数据,避免过早或过晚的加载导致页面空白时间过长。可采用以下 代码实现延迟加载。在Activity的onCreate方法中:

getWindow().getDecorView().post(new Runnable() {
  @Override
  public void run() {
    myHandler.post(mLoadingRunnable);
  }
});
2.2 异步加载

将不需要首次加载的初始化内容放入子线程进行初始化。

3.UI布局优化

-避免多级嵌套,采用constraintlayout布局代替嵌套的LinearLayout;

-复杂布局,使用include

-删除无用布局

4.MultiDex初次启动优化

4.1问题

随着代码数量的膨胀,工程本身的代码加上引用的第三方库的代码中方法数量会超过65536的限制。是由于DEX文件格式限制,一个DEX文件中method个数采用使用原生类型short来索引文件中的方法,也就是4个字节共计最多表达65536个method,field/class的个数也均有此限制。 Google为构建超过65K方法数的应用提供官方支持的方案:MultiDex。

但是在Dalvik下MultiDex有个问题:5.0以下某些低端机会出现ANR或者长时间卡顿不进入引导页,而罪魁祸首是MultiDex.install(Context context)的dexopt过程耗时过长。因此需要在初次启动时做特别处理。

而5.0以上会使用ART,在ART下MultiDex是不存在这个问题的,这主要是因为ART下采用Ahead-of-time (AOT) compilation技术,系统在APK的安装过程中会使用自带的dex2oat工具对APK中可用的DEX文件进行编译并生成一个可在本地机器上运行的文件,这样能提高应用的启动速度,只是在安装过程中进行了处理这样会影响应用的安装速度。

4.2解决思路

1、在Application.attachBaseContext(Context base)中,判断是否初次启动,以及系统版本是否小于5.0,如果是,跳到2;否则,直接执行MultiDex.install(Context context)。

2、开启一个新进程,在这个进程中执行MultiDex.install(Context context)。执行完毕,唤醒主进程,自身结束。主进程在开启新进程后,自身是挂起的,直到被唤醒。

1、在Application.attachBaseContext(Context base)中,判断是否初次启动,以及系统版本是否小于5.0,如果是,跳到2;否则,直接执行MultiDex.install(Context context)。

2、开启一个新进程,在这个进程中执行MultiDex.install(Context context)。执行完毕,唤醒主进程,自身结束。主进程在开启新进程后,自身是挂起的,直到被唤醒。

3、唤醒的主进程继续执行初始化操作。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值