Android 基础之性能优化(二)

作者: Kevin_小飞象 | 来源:发表于2019-02-21 14:25 被阅读0次

启动速度优化

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>

效果图:


image

方案二:主题替换
我们在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);    
}

效果图:


image

无论何种启动,我们的优化点都是: Application、Activity创建以及回调等过程。
谷歌官方给的建议是:
1、利用提前展示出来的Window,快速展示出来一个界面,给用户快速反馈的体验;
2、避免在启动时做密集沉重的初始化(Heavy app initialization);
3、避免I/O操作、反序列化、网络操作、布局嵌套等。

包体优化

我们需要从代码和资源两个方面去减少 apk 的大小:

  1. 首先我们可以使用 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'
        }
    }
  1. 能自己用 xml 写 Drawable,就自己写。
  2. 重用资源,比如一个三角按钮,点击前三角朝上代表收起的意思,点击后三角朝下,代表展开,一般情况下,我们会用两张图来切换,我们完全可以用旋转的形式去改变
  3. 代码混淆
  4. 插件化

耗电优化

谷歌推荐使用 JobScheduler,来调整任务优先级等策略来达到降低损耗的目的。
JobScheduler 可以避免频繁的唤醒硬件模块,造成不必要的电量消耗。避免在不合适的时间(例如低电量情况下、弱网络或者移动网络情况下的)执行过多的任务消耗电量。

ListView和 Bitmap优化

  • ListView使用ViewHolder,分段,分页加载
  • 压缩Bitmap

响应速度优化

影响响应速度的主要因素是主线程有耗时操作,影响了响应速度。所以响应速度优化的核心思想是避免在主线程中做耗时操作,把耗时操作异步处理。

线程优化

线程优化的思想是采用 线程池,避免在程序中存在大量的Thread。线程池可以重用内部的线程,从而避免了现场的创建和销毁所带来的性能开销,同时线程池还能有效地控制线程池的最大并发数,避免大量的线程因互相抢占系统资源从而导致阻塞现象发生。

相关文章

网友评论

    本文标题:Android 基础之性能优化(二)

    本文链接:https://www.haomeiwen.com/subject/ghcryqtx.html