我知道的Android-性能优化

APP的性能优化是永恒的主题,今天我们来详细梳理一下。

1.布局优化

APP的最主要的功能就是展示,布局就是最直观的展示效果,渲染布局的工作是复杂的。
布局的根部是一个ViewGroup组件,多个ViewGroup的嵌套,就使得View树变得更大,布局的层级也越来越深,最终影响我们应用的性能。

1.1 减少布局嵌套

我们常用的ViewGroup有三种:LineraLayout,FrameLayout,RelativeLayout,FrameLayout相对来说比较特殊,就不去讨论了。在LinearLayout和RelativeLayout的选择上我们要灵活考虑,在不涉及层级嵌套的前提下,我们尽可能使用LinearLayout,LinearLayout的测量会比Relative
Layout更加快速,因为RelativeLayout是相对布局,要考虑上下和左右方向的测量。

1.2 使用Google提供的标签

Google为我们提供了includemerge,ViewStub三种标签,下面我简单介绍一下用法。

  1. include主要用于布局的重用。
    这里写图片描述

  2. merge主要用于减少层级嵌套。
    这里写图片描述

  3. ViewStub主要是实现一种按需加载。简单来说就是由代码控制布局的加载时机。
    这里写图片描述

1.3 最新引入的布局—约束布局(ConstraintLayout)

约束布局是Google提供给我来减少布局嵌套的新布局,感觉起来和RelativeLayout差不多,但是ConstraintLayout更加强大,给大家一个ConstraintLayout用法介绍

2.绘制优化

这个优化主要是针对我们在自定义View的时候,布局和绘制是影响我们显示的两个因素,布局优化的提升效果可能不是那么明显,我们平时感觉到的卡顿还是绘制的问题,Android的绘制机制是每隔16ms发出信号,对UI进行渲染绘制,但是这期间有不少的未知因素的影响,严重的就会造成卡顿等问题,绘制的方法主要就是onDrae()了,所以:

  1. 我们在onDraw()的方法里面不要做耗时任务,这会极大的影响绘制的流畅度。
  2. 我们不要再onDraw()方法里面频繁的创建局部变量,因为onDraw()方法的调用频率很高,过多的局部变量会对性能照成损耗,最终会影响性能。

3.内存优化

在内存优化里面有一个不得不提的概念—内存泄漏,泄漏的意思就是,有一部分的内存我们不能再管理了,因为对象的引用被另外的对象持有,而且持有引用的对象的生命周期还比较长,造成了这块内存不能回收再利用。

集合造成的泄漏

集合类会持有集合内部对象的引用,我们应该在不使用的时候,进行集合的释放。

静态造成泄漏

静态的声明周期贯穿整个程序,非常容易造成内存的泄漏。在我们传递引用的时候,大部分会是Context对象,这时我们有两种方式来解决内存泄漏的问题:

  1. 使用全局的Context对象,就是Application对象,Application的生命周期也很长,不存在内存泄漏的问题。
  2. 使用弱引用或者软引用包裹Context对象,使用get()方法来调用包裹Context对象。

内部类造成内存泄漏

内部类会隐式的持有外部类的引用,而且内部类的生命周期可能比外部类时间更长,所有有很大可能造成内存泄漏。解决的办法就是声明称静态的内部类。

资源没有及时关闭造成

这个就主要靠我们平时自己注意了,比如I/O流,动态注册广播,Service调用stopSelf()方法(onStartCommand()执行完毕之后,再调用onDestroy())等。

关于内存优化有几个工具是比较常用的:leakcanaryAndroid LintAndroid Profiler

4.启动优化

Android的启动一般分为3种方式,分别是:冷启动,暖启动,热启动。启动方式的不同,影响了APP可见时需要的时间,而冷启动才是我们最要关注的一种。

冷启动

每一个Android程序都需要进程来维持运行,当我们程序需要的进程还没有创建的时候,这时APP就会采用冷启动的方式,冷启动一般发生在APP第一次启动或者手动停止之后再次启动。

冷启动发生时,系统会做三个任务:

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

进程创建好了之后,接着就开始创建应用程序对象:

  1. 初始化应用的对象(Application的初始化)
  2. 启动主线程
  3. 创建MainActivity
  4. 加载xml布局
  5. 计算布局再屏幕上的位置
  6. 绘制布局

第一次绘制完成之后,空白启动窗就会被Activity的内容替换掉,这个时候我们才可以和用户进行交互了。

暖启动

暖启动包含了冷启动的一些操作,但是它的开销上更节省,一般在应用退出与重启时,会发生暖启动。

热启动

热启动的速度上是最快的,如果activity还在内存当中,它不需要初始化和布局加载、绘制的过程。在热启动的时候,系统也会显示一个空白的屏幕,直到Activity处于可见的状态。

通过上面的了解,我们知道了优化的重点在于,Application和MainActivity的onCreate()的方法里面,我们要尽可能的减少耗时操作:

  1. 异步加载与主业务关联较少的框架。
  2. 非第一时间使用的功能可以采用延时加载

谷歌官方建议我们:

  1. 利用开始的空白的window,展示出一个界面,给用户一个快速的反馈。
  2. 避免在启动的时候,做出密集的初始化。

利用空白window

我们可以利用主题中的android:windowBackground属性,可以给window设置一个背景,用于初始化的时候进行展示。

 <style name="StartAppTheme" parent="AppTheme">
        <item name="android:windowBackground">@drawable/start_app_bg</item>
    </style>

再在AndroidManifest.xml文件里面设置主题

  <activity
            android:name=".MainActivity"
            android:theme="@style/StartAppTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

然后我们在MainActivty的onCreate()的设置为正常主题


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //把主题改成正常状态
        setTheme(R.style.AppTheme);
        setContentView(R.layout.activity_main);

以上。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值