Android问题集

Android启动性能优化

2018-09-06  本文已影响32人  炉石旁的猫

从两个方向优化应用的启动速度

视觉体验优化
代码逻辑优化

应用程序启动有三种状态,每种状态都会影响应用程序对用户可见所需的时间:冷启动,热启动和温启动。

在冷启动时,应用程序从头开始。在其他状态下,系统需要将正在运行的应用程序从后台运行到前台。我们建议您始终根据冷启动的假设进行优化。这样做也可以改善热启动和温启动的性能。

在冷启动开始时,系统有三个任务。这些任务是:

1、加载并启动应用程序。

2、启动后立即显示应用程序空白的启动窗口。

3、创建应用程序进程。

一旦系统创建应用程序进程,应用程序进程就会负责下一阶段。

这些阶段是:

1、创建app对象.

2、启动主线程(main thread).

3、创建应用入口的Activity对象.

4、填充加载布局Views

在屏幕上执行View的绘制过程.measure -> layout -> draw

应用程序进程完成第一次绘制后,系统进程会交换当前显示的背景窗口,将其替换为主活动。此时,用户可以开始使用该应用程序

冷启动阶段 :

  1. 加载并启动应用程序。
  2. 启动后立即显示应用程序空白的启动窗口。
  3. 创建应用程序进程。

第一步 去白屏 优化感受
设置闪屏图片主题
为了更顺滑无缝衔接我们的闪屏页,可以在启动 Activity 的 Theme中设置闪屏页图片,这样启动窗口的图片就会是闪屏页图片,而不是白屏

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:windowBackground">@mipmap/launch</item> //闪屏页图片
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>

其实这种方式并没有真正的加速应用进程的启动速度,而只是通过用户视觉效果带来的优化体验。

参考如何计算 App 的启动时间

http://www.androidperformance.com/2015/12/31/How-to-calculation-android-app-lunch-time/

adb命令 : adb shell am start -S -W 包名/启动类的全路径名 , -S 表示重启当前应用
adb shell am start -S -W com.example.zhangz.demo/com.example.zhangz.demo.activity.MainActivity

image.png

1、ThisTime : 最后一个 Activity 的启动耗时(例如从 LaunchActivity - >MainActivity「adb命令输入的Activity」 , 只统计 MainActivity 的启动耗时)

2、TotalTime : 启动一连串的 Activity 总耗时.(有几个Activity 就统计几个)

3、WaitTime : 应用进程的创建过程 + TotalTime .

image.png

第二步 Application 优化
将Bugly,x5内核初始化,SP的读写,友盟等组件放到子线程中初始化。(子线程初始化不能影响到组件的使用)
new Thread(new Runnable() {
@Override
public void run() {
//设置线程的优先级,不与主线程抢资源
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//子线程初始化第三方组件
Thread.sleep(5000);//建议延迟初始化,可以发现是否影响其它功能,或者是崩溃!
}
}).start();
将需要在主线程中初始化但是可以不用立即完成的动作延迟加载(原本是想在入口 Activity 中进行此项操作,不过组件的初始化放在 Application 中统一管理为妙.)
handler.postDelayed(new Runnable() {
@Override
public void run() {
//延迟初始化组件
}
}, 3000);

第二步 闪屏页优化


image.png

如何统计Android App启动时间

https://www.jianshu.com/p/59a2ca7df681

分析源码后,我们可以知道 Application 初始化后会调用 attachBaseContext() 方法,再调用 Application 的 onCreate(),再到入口 Activity的创建和执行 onCreate() 方法。所以我们就可以在 Application 中记录启动时间

@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
LogUtil.e("application_attach_time:"+ System.currentTimeMillis());//记录Application初始化时间
}

//入口Activity
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);

  long appAttachTime = SPUtil.getLong("application_attach_time");
  long diffTime = System.currentTimeMillis() - appAttachTime;//从application到入口Acitity的时间

 //所以闪屏页展示的时间为 2000ms - diffTime.

}

所以我们就可以动态的设置应用闪屏的显示时间,尽量让每一部手机展示的时间一致,这样就不会让手机配置较低的用户感觉漫长难熬的闪屏页时间(例如初始化了2000ms,又要展示2000ms的闪屏页时间.),优化用户体验。

第四部 广告页优化

闪屏页过后就要展示金主爸爸们的广告页了。

因为项目中广告页图片有可能是大图,APng动态图片,所以需要将这些图片下载到本地文件,下载完成后再显示,这个过程往往会遇到以下两个问题 :

广告页的下载,由于这个是一个异步过程,所以往往不知道加载到页面的合适时机。

广告页的保存,因为保存是 I/O 流操作,很有可能被用户中断,下次拿到破损的图片。

因为不清楚用户的网络环境,有些用户下载广告页可能需要一段时间,这时候又不可能无限的等候。所以针对这个问题我们可以开启 IntentService 用来下载广告页图片。

在入口 Acitivity 中开启 IntentService 来下载广告页。 或者是其它异步下载操作。

在广告页图片 文件流完全写入后 记录图片大小,或者记录一个标识。

在下次的广告页加载中可以判断是否已经下载好了广告页图片以及图片是否完整,否则删除并且再次下载图片。

另外因为在闪屏页中仍然有 剩余展示时间,所以在这个时间段里如果用户已经下载好了图片并且图片完整,就可以显示广告页。否则进入主 Activity , 因为 IntentService 仍然在后台继续默默的下载并保存图片~

上一篇下一篇

猜你喜欢

热点阅读