APP优化 启动速度优化

一.关键词

 

1.冷启动

   当点击应用图标启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用。这个启动方式就是冷启动。

   因为冷启动每次都会创建初始化Application,所以ApplicationonCreate方法每次都会执行。也就是对应的APP级别的初始化方法都会执行,所以相对耗时多一点。

 

 

 

2.热启动

   当点击应用图标启动应用时,后台已有该应用的进程(例如:按返回键退出APP,应用虽然退出,但是该应用的进程依然保留在后台,任务列表可查看),所以在已有进程的情况下,这种启动会从已有进程中启动应用。这个启动方式就是热启动。

   因为热启动不会再创建初始化Application,只会重新创建初始化相关的Activity。所以耗时相对较少。

 

 

 

 

 

 

 

二.启动优化方案

 

APP的启动速度可能直接影响APP的使用情况,所以启动优化方案是必现的。下面讲解常用的几个方案。

 

1.启动黑屏问题

这么做的目的是启动时的黑白屏,给用户一种秒响应的感觉。其实不是真正减少启动时间,属于视觉错觉。

 

<1> 启动黑屏原因

Activity生命周期onCreate(),onStart(),onResume()方法。一次执行完这三个方法,APP才可和用户进行交互。如果这三个方法中执行了耗时操作,阻塞了主线程,很明显就会出现黑白屏问题。还有就是即使onResume()方法没有执行还是会出现黑白屏问题,原因就是加载界面需要短暂的时间。

 

<2> 解决方法

将启动页主题背景设置成闪屏页图片

 

自定义背景图样式

<style name="FristActivityTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="android:windowBackground">@mipmap/XXX.png</item>
</style>

 

清单文件使用样式

<activity
    android:name=".index.SplashActivity"
    android:screenOrientation="portrait"
    android:theme="@style/FristActivityTheme">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
 
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

 

Activity可能要还原主题

package com.example.test;

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setTheme(R.style.AppTheme);


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

}

 

这种操作,其实是假象。主要给用户错觉。其实没有做到真正的启动优化。

 

 

 

 

2.异步或延时

项目中Application或者宿主Activity的onCreate中难免会初始化很多操作(比如 离线包初始化,高德地图初始化,APP数据库初始化等等)。如果一股脑的将这些初始化全部放到主线程中进行会降低启动速度。

 

所以可以把一些耗时的操作,比如 文件解压、读写、操作数据库等耗时 IO 操作到子线中执行。

还有一些初始化优先级比较低的(比如 WebView的一些初始化,因为只有进H5页面才会用到)。像这样的初始化可以延时加载,(即这种类似的操作可以放到某个用到的Activity中初始化,不必都集中到Application中初始化)这样的操作就不会影响启动耗时了。但是延时只能是延时一些优先级较低的。要避免延时初始化的内容,一进APP就使用,比如我遇到过的,锁屏推送埋点的问题。

 

子线程需要用到线程池

https://blog.csdn.net/weixin_37730482/category_6876446.html

 

 

 

 

 

3.其他优化

比如A页面显示十五个ICON是接口获取的。进入B页面可以编辑,编辑之前要显示A页面的十五个ICON。那么B页面显示的编辑之前默认的十五个ICON就不用了接口请求。直接使用A页面请求回来的Json数据。同样B编辑成功后返回十五个新的ICON,回到A页面后,A页面也不必请求接口,直接解析B页面编辑成功后保存的Json数据即可。这样进入A页面—B页面编辑—A页面刷新,请求两个接口一遍即可。

 

 

 

 

 

 

 

二.启动耗时检测

 

下面讲解几种查看APP启动耗时的方法,来监控APP的启动速度。

 

1.代码打点

代码

package com.example.test;

import android.os.Bundle;
import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initMethod();
    }

    public void initMethod() {

        long starttime = System.currentTimeMillis();

        for (int i = 0; i < 1000000; i++) {
            String s = String.valueOf(i);
        }


        long endtime = System.currentTimeMillis();


        long time = endtime - starttime;

        Log.i("TAG", "测试方案耗时time----:" + time);

    }

}

 

结果

I/TAG: 测试方案耗时time----:180

 

 

 

2.查看Logcat

谷歌在 Android4.4(API 19)上也提供了测量方法,​​​​​​​在AndroidStudio Logcat中过滤关键字 “Displayed” ,来查看应用冷启动耗时日志。

结果

ActivityManager: Displayed com.example.test/.MainActivity: +238ms


ActivityManager: Displayed com.XXX/.webview.XXXActivity: +284ms


ActivityManager: Displayed com.XXX/.widget.XXX.view.XXXActivity: +286ms

 

 

3.命令行1

使用adb shell 获取应用的启动时间。

adb shell am start -W [包名]/[入口Activity全路径]

 

执行后会得到三个时间。

ThisTime:最后一个Activity启动耗时。

TotalTime:所有Activity启动耗时。

WaitTime:AMS启动Activity的总耗时。

 

输入

D:\Android\save\android-demo>adb shell am start -W com.XX/com.XX.main.activity.XXActivity

 

结果

 

<1> 进入首页

Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.XX/.main.activity.XXXActivity }
Warning: Activity not started, its current task has been brought to the front
Status: ok
Activity: com.bankcomm/.main.activity.AAAActivity
ThisTime: 0
TotalTime: 0
WaitTime: 4
Complete

 

<2> 首页点击进入另一个Activity

Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.XXX/.main.activity.XXXActivity }
Warning: Activity not started, its current task has been brought to the front
Status: ok
Activity: com.XXX/.webview.BBBActivity
ThisTime: 0
TotalTime: 0
WaitTime: 8
Complete

 

 

 

 

4.命令行2

adb shell 然后输入 logcat -b events|grep am_activity_launch_time

 

输入

D:\Android\save\android-demo>adb shell
NX606J:/ $ logcat -b events|grep am_activity_launch_time

 

结果

I am_activity_launch_time: [0,124154950,com.XXX/.main.activity.AAAActivity,488,488]

I am_activity_launch_time: [0,161791135,com.XXX/.webview.BBBActivity,284,284]

I am_activity_launch_time: [0,151415468,com.XXX/.widget.XXX.view.CCCActivity,286,286]

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值