AndroidUI性能优化-卡顿优化

 

Android性能优化分类

  • 卡顿优化
  • 内存优化
  • 电量优化
  • 网络优化
  • 启动优化、安装包体积优化

UI界面是app和用户打交道的部分,直接对用户形成品牌意识,需要仔细的设计。性能优化都需要有一个目标,UI的性能优化也是一样。你可能会觉得“我的app加载很快”很重要,但我们还需要了解终端用户的期望。

我们可以从人机交互心理学的角度来考虑这个问题。研究表明,0-100毫秒以内的延迟对人来说是瞬时的,100-300毫秒则会感觉明显卡顿,300-1000毫秒会让用户觉得“手机卡死了”,超过1000ms就会让用户想去干别等事情了。

这是人类心理学最基础的理论,如果网页在3-4秒内还没加载出任何内容,用户就会放弃了。把这些数据应用到app的加载,不难明白加载时间是越短越好。

对于开发过程,出现卡顿的主要原因是主线程做了一些不该做的事,或者主线程做不了事情了。

卡顿优化

卡顿:从用户角度说,App操作起来缓慢,响应不及时,列表滑动一顿一顿的,动画刷新不流畅等等一些直观感受。从系统角度来说,屏幕刷新的帧率不稳定,无法保证每秒绘制60帧,也就是说有掉帧的情况发生。

  • 布局渲染(解析、测量、布局、渲染)
  • 动画执行
  • Binder通信
  • 界面响应

主线程主要是做以上四个方面的工作,如果在主线程做一些耗时操作(网络请求、IO读写等),或者被其他线程挂起(GC),那么页面刷新无法在16ms内完成,就会出现掉帧的情况。

1,布局渲染

大家应该都对android studio里xml布局编辑器很熟悉了,搭建这些view的时候,一定要留意屏幕右上角的组件树(Component Tree)。套嵌的子view越深,组件树就越复杂,渲染起来也就越费时间,layout尽量不要超过5层,层级的减少,从而达到结构清晰,渲染速度快的效果。顺着这个逻辑,布局优化分为重用、合并、按需载入。

重用< include/>

< include>标签可以在一个布局中引入另外一个布局,这个的好处显而易见,比如项目头部栏:左上角返回图标,

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:background="@color/background"
    android:layout_height="48dp">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:src="@drawable/icon"/>

    <TextView
        tools:text="当前界面标题"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textSize="18sp"
        android:textColor="@color/white" />

    <TextView
        tools:text="右边功能按钮"
        android:layout_width="wrap_content"
        android:gravity="center"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:textSize="16sp"
        android:textColor="@color/white" />

</RelativeLayout>

在不同的xml上引用,也可以写成一个基类,供给继承当前BaseActivity的类头部状态栏。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <include
        layout="@layout/title_bar"/>

</RelativeLayout>

合并,减少嵌套

首先我们心中要有一个大原则:尽量保持布局层级的扁平化。在这个大原则下我们要知道:

在不影响层级深度的情况下,使用LinearLayout而不是RelativeLayout。因为RelativeLayout会让子View调用2次onMeasure,LinearLayout 在有weight时,才会让子View调用2次onMeasure。Measure的耗时越长那么绘制效率就低。

如果非要是嵌套,那么尽量避免RelativeLayout嵌套RelativeLayout

< merge/>主要用来去除不必要的FrameLayout。它的使用最理想的情况就是你的根布局是FrameLayout,同时没有使用background等属性。这时可以直接替换。因为我们布局外层就是FrameLayout,直接“合并”。

<?xml version="1.0" encoding="utf-8"?>
<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <include
        layout="@layout/title_bar"/>

</merge>

我们还可以这样使用,减少一层RelativeLayout。

<?xml version="1.0" encoding="utf-8"?>
<merge
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:src="@drawable/icon_back_1"/>

    <TextView
        android:layout_gravity="center_horizontal"
        android:text="标题"
        android:gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:layout_centerInParent="true"
        android:textSize="18sp"
        android:textColor="@color/black" />

    <TextView
        android:text="确定"
        android:layout_gravity="right"
        android:layout_width="wrap_content"
        android:gravity="center"
        android:layout_height="48dp"
        android:layout_alignParentRight="true"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:textSize="16sp"
        android:textColor="@color/black" />

</merge>

用TextView同时显示图片和文字;效果如下:

这种效果很常见,一般实现方法是这样。最后放在一个ListView或者RecyclerView里面,就能做出一排出来,并且有分界线

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
                android:background="@color/white"
                android:id="@+id/rl_layout"
              android:layout_width="match_parent"
                android:minHeight="?android:attr/listPreferredItemHeight"
              android:layout_height="120px">

    <TextView
        android:layout_toRightOf="@+id/item_fgmelist_img"
        android:id="@+id/item_fgmelist_tv"
        android:gravity="center"
        android:layout_centerVertical="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我的消息"
        android:textColor="#FF333333"
        android:textSize="28px"
        />

    <ImageView
        android:id="@+id/item_fgmelist_img"
        style="@style/left_right"
        android:src="@mipmap/personal"
        android:layout_centerVertical="true"
        android:layout_width="64px"
        android:layout_height="64px"/>

    <ImageView
        android:layout_marginRight="28px"
        android:layout_centerVertical="true"
        android:layout_alignParentRight="true"
        android:src="@mipmap/path"
        android:layout_width="16px"
        android:layout_height="26px"/>
    
    <View
        android:layout_alignParentBottom="true"
        android:layout_marginLeft="28px"
        android:background="@color/bg_line"
        android:layout_width="match_parent"
        android:layout_height="1px"/>

</RelativeLayout>

这样写层级太多,不易于处理,这样处理就可以减少几次渲染。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:drawableLeft="@drawable/personal"
        android:drawableRight="@drawable/path"
        android:drawablePadding="10dp"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:textSize="16sp"
        android:text="我的消息"
        android:background="@color/white"
        android:gravity="center_vertical"
        android:layout_width="match_parent"
        android:layout_height="120px" />

</LinearLayout>

按需载入ViewStub

ViewStub是一个轻量级的View,不占布局位置,占用资源非常小。用法很简单,一旦ViewStub可见或是被inflate了,ViewStub就不存在了,取而代之的是被inflate的Layout。所以它也被称做惰性控件。

     ViewStub viewStub = (ViewStub)this.findViewById(R.id.hint_view);
     hintView = viewStub.inflate();
     TextView textView = (TextView) hintView.findViewById(R.id.tv);
     textView.setText("显示内容");

Space控件

如果要给中间添加间距,怎么实现呢?当然也很简单,比如添加一个高10dp的View,或者android:layout_marginTop="10dp"等方法。但是增加View违背了我们的初衷,并且影响性能。使用过多的margin其实会影响代码的可读性。

    <Space
        android:layout_width="match_parent"
        android:layout_height="15dp"/>

最后,便是约束布局;

ConstraintLayout,增强型RelativeLayout

在 Android Studio 2.3 版本中新建的Module中默认的布局就是 ConstraintLayout 。如下所示:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</android.support.constraint.ConstraintLayout>
  • 传统的Android开发当中,界面基本都是靠编写XML代码完成的,而ConstraintLayout和传统编写界面的方式恰恰相反,ConstraintLayout非常适合使用可视化的方式来编写界面,但并不太适合使用XML的方式来进行编写。
  • ConstraintLayout 还有一个优点,它可以有效地解决布局嵌套过多的问题。我们平时编写界面,复杂的布局总会伴随着多层的嵌套,而嵌套越多,程序的性能也就越差。ConstraintLayout则是使用约束的方式来指定各个控件的位置和关系的,它有点类似于 RelativeLayout,但远比RelativeLayout要更强大。

进入操作界面,如下图:

具体的使用,就不在这里详细介绍了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值