启动速度优化
app启动分为冷启动(Cold start)、热启动(Hot start)和温启动(Warm start)三种。
冷启动(Cold start)
冷启动是指APP在手机启动后第一次运行,或者APP进程被kill掉后在再次启动。
可见冷启动的必要条件是该APP进程不存在,这就意味着系统需要创建进程,APP需要初始化。在这三种启动方式中,冷启动耗时最长,对于冷启动的优化也是最具挑战的。
温启动(Warm start)
App进程存在,当时Activity可能因为内存不足被回收。这时候启动App不需要重新创建进程,但是Activity的onCrate还是需要重新执行的。场景类似打开淘宝逛了一圈然后切到微信去聊天去了,过了半小时再次回到淘宝。这时候淘宝的进程存在,但是Activity可能被回收,这时候只需要重新加载Activity即可。
热启动(Hot start)
App进程存在,并且Activity对象仍然存在内存中没有被回收。可以重复避免对象初始化,布局解析绘制。
场景就类似你打开微信聊了一会天这时候出去看了下日历 在打开微信 微信这时候启动就属于热启动。
从点击APP图标到主页显示出现需要经过的步骤:
1.创建应用程序对象
2.启动主线程
3.创建主要Activity
4.绘制视图(View)
5.布局屏幕
6.执行初始化绘制
启动速度优化
如何对启动时间进行量化?
1.目前为止见过最最牛逼的是使用机械手和高速相机测试,手机开机后使用机械手点击应用桌面图标,高速相机记录启动过程,后续通过程序分析视频,从机械手点击图标到Activity显示出来使用了多少时间。这种方式是最直观和精确的,但是成本也很高。
2.通过shell 命令
adb shell am start -W [packageName]/[packageName.MainActivity]
执行成功后将返回三个测量到的时间:
ThisTime:一般和TotalTime时间一样,除非在应用启动时开了一个透明的Activity预先处理一些事再显示出主Activity,这样将比TotalTime小。
TotalTime:应用的启动时间,包括创建进程+Application初始化+Activity初始化到界面显示。
WaitTime:一般比TotalTime大点,包括系统影响的耗时。
3.可以通过在代码中增加log来计算启动时间
4.使用systrace
如何消除启动时的白屏/黑屏?
方案一:甩锅给系统
Activity.onCreate()之前App不做显示,这样用户误以为是手机慢了,这种瞒天过海的方案大家还是不要用了。
使用透明主题:
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowIsTranslucent">true</item>
</style>
</resources>
效果图:
方案二:主题替换
我们在style中自定义一个样式 Lancher,在其中放一张背景图片,或是广告图片之类的
<style name="AppTheme.Launcher">
<item name="android:windowBackground">@drawable/bg</item>
</style>
把这个样式设置给启动的Activity:
<activity
android:name=".activity.SplashActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.Launcher"
>
然后在Activity的onCreate方法,把Activity设置回原来的主题
@Override
protected void onCreate(Bundle savedInstanceState) {
//替换为原来的主题,在onCreate之前调用
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
}
效果图:
无论何种启动,我们的优化点都是: Application、Activity创建以及回调等过程。
谷歌官方给的建议是:
1、利用提前展示出来的Window,快速展示出来一个界面,给用户快速反馈的体验;
2、避免在启动时做密集沉重的初始化(Heavy app initialization);
3、避免I/O操作、反序列化、网络操作、布局嵌套等。
包体优化
我们需要从代码和资源两个方面去减少 apk 的大小:
- 首先我们可以使用 lint 工具,如果没有使用过的资源就会打印如下的信息:
res/layout/preferences.xml: Warning: The resource R.layout.preferences appears to be unused [UnusedResources]
同时我们可以开启资源压缩,自动删除无用的资源
android {
...
buildTypes {
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
- 能自己用 xml 写 Drawable,就自己写。
- 重用资源,比如一个三角按钮,点击前三角朝上代表收起的意思,点击后三角朝下,代表展开,一般情况下,我们会用两张图来切换,我们完全可以用旋转的形式去改变
- 代码混淆
- 插件化
耗电优化
谷歌推荐使用 JobScheduler,来调整任务优先级等策略来达到降低损耗的目的。
JobScheduler 可以避免频繁的唤醒硬件模块,造成不必要的电量消耗。避免在不合适的时间(例如低电量情况下、弱网络或者移动网络情况下的)执行过多的任务消耗电量。
ListView和 Bitmap优化
- ListView使用ViewHolder,分段,分页加载
- 压缩Bitmap
响应速度优化
影响响应速度的主要因素是主线程有耗时操作,影响了响应速度。所以响应速度优化的核心思想是避免在主线程中做耗时操作,把耗时操作异步处理。
线程优化
线程优化的思想是采用 线程池,避免在程序中存在大量的Thread。线程池可以重用内部的线程,从而避免了现场的创建和销毁所带来的性能开销,同时线程池还能有效地控制线程池的最大并发数,避免大量的线程因互相抢占系统资源从而导致阻塞现象发生。
网友评论