当前位置:首页 » 新媒体运营 » 正文

新产品发朋友圈广告语,刚上架的APP,如何做好优化?

5696 人参与  2022年11月03日 14:35  分类 : 新媒体运营  评论


Android 绘制原理及工具选择

在计算机硬件中,通常 CPU 用来处理数据,GPU 用来渲染数据,Android 系统也不例外,绘制过程首先是 CPU 准备数据,通过 Driver 层把数据交给 GPU 渲染,其中 CPU 主要负责 Measure、Layout、Record、Execute 的数据计算工作,GPU 负责 Rasterization(栅格化)、渲染。

无论是 CPU 准备的数据,还是 GPU 要渲染的数据,都是一帧一帧的形式。我们看到的界面也是由一帧一帧的图像连续显示而来。对于人眼来说,每秒看到 帧是比较流畅的,即 FPS(Frame Per Second)为 ,/ = .,即每 ms进行一次准备、渲染工作。

常用的布局优化工具有以下几种:

Systrace,内存优化工具中也用到了 Systrace,这里关注 Systrace 中的 Frames 页面,正常情况下圆点为绿色,当出现黄色或者红色的圆点时,表现出现了丢帧。

Layout Inspector,是 AndroidStudio 自带工具,可以查看页面的视图层次结构。

Choreographer,是Android加入的一个工具类,通过 Choreographer.getInstance().postFrameCallback,可以实时获取 FPS。

Android 的布局加载时 IO 操作,比如 xml 文件要通过 xml 解析器才能加载到内存里。在加载 xml 文件的时候,还会用到反射,而反射本来性能就不高。

.优雅获取界面布局耗时

在对布局优化前,我们需要找到一个指标,作为衡量布局优化效果的标准。常用有下面几种方式来获取页面加载的耗时。

常规方式,通过手动埋点的方式来确认页面加载的耗时,这种方式代码侵入性强,工作量大,不便于后期的维护。

AOP 方式,通过对 Activity 的 setContentView()方法切片,获取加载每个页面的耗时,这种方式代码侵入性小。

通过上面的方式可以获取页面加载的耗时,为了更加精细化的优化,如何获取每个控件加载的耗时呢? 可以通过 LayoutInflater.Factory(考虑兼容性可以使用
LayoutInflaterCompat.setFactory) 来实现,这种方式代码侵入性小。通过自定义 Factory,在 onCreateView() 方法的中实现对每个控件加载耗时的计算。使用时需要注意,这个设置应该在super.onCreate()之前,否则无效。

public interface Factory {        /**
         * Hook you can supply that is called when inflating from a LayoutInflater.
         * You can use this to customize the tag names available in your XML
         * layout files.
         *
         * <p>
         * Note that it is good practice to prefix these custom names with your
         * package (i.e., com.coolcompany.apps) to avoid conflicts with system
         * names.
         *
         * @param name Tag name to be inflated.
         * @param context The context the view is being created in.
         * @param attrs Inflation attributes as specified in XML file.
         *
         * @return View Newly created view. Return null for the default
         *         behavior.
         */        public View onCreateView(String name, Context context, AttributeSet attrs);
.异步 Inflate

前面介绍到布局文件加载的过程是一个 IO 过程,创建对象时还使用到反射,使用反射创建对象的速度比通过 new 关键字创建要慢 倍左右。所以布局优化的方向是尽量减少 IO 过程,减少通过反射来创建对象。

这里介绍一种侧面优化布局的方式即异步实现布局的加载。AsyncLayoutInflater 是一个异步初始化布局的 Helper 类。它的本质就是把对布局文件的 inflate 放入到了子线程里面,等到初始化成功后,在通过接口抛回到主线程。

.布局加载优化

有没有一种方法从根本上来解决io操作慢、反射慢的问题呢?答案是直接用 Java 代码写布局文件,这样会引入新问题,不便于开发、可维护性差。用 xml 来写布局,虽然IO慢、反射慢,因为方便维护,可读性好,还方便写UI时进行预览。那有没有一个方案既能保留XML优点,还能解决其性能问题呢?XC 就是这样一个方案。

XC 的原理是在 APT 编译期将需要翻译的布局 xml 文件翻译生成对应的 java 文件,这样对于开发人员来说写布局还是写原来的 xml ,但对于程序来说,运行时加载的是对应的 java 文件。

不论是异步加载 AsyncLayoutInflater,还是 XC 方案,都要考虑下面的问题:

控件的一部分属性在 xml 文件中使用是可以的,在 Java 代码中是不支持的,这部分属性虽然很少,但还是存在,使用的时候需要注意。新产品发朋友圈广告语,刚上架的APP,如何做好优化?-百度竞价优化_微商推广_今日头条自媒体_新媒体运营_剑谦网络

另外一个问题是失去了系统的兼容性,无法使用 AppCompat 等兼容类,无法做到控件的向下兼容。这时就要考虑对两种方案进行定制,来获得兼容性。

.视图绘制优化实战

前面对布局优化的方案都是针对布局加载进行优化的,这里介绍一下在视图绘制时的优化方案。Android 中的视图绘制要经历三个过程:

测量,在测量阶段确定视图的大小;

布局,在布局阶段确定视图的位置;

绘制,在绘制阶段完成视图的绘制。

三个过程的实现都会涉及 View 树自顶向下的遍历,有时甚至还会触发多次,所以每个阶段都会出现耗时的情况,都是我们去优化的方向。布局优化在绘制阶段的准则是尽量减少 View 树的层级,页面布局要做到宽而浅、避免窄而深。

ConstraintLayout 是在 Android Studio . 中主要的新增功能之一,它可以有效地解决布局嵌套过多的问题,实现几乎完全扁平化布局,构建复杂布局的性能更高,它有点类似于RelativeLayout,但远比RelativeLayout要更强大。

除了使用 ConstraintLayout,还可以考虑以下的优化方式:

不嵌套使用 RelativeLayout;

不在嵌套的 LinearLayout 中使用 weight 属性;

使用 merge 标签,可以减少一个 view 层级,但是只能用在根 View 中;

过度绘制就是在同一个区域中叠加了多个控件,重复的叠加就是过度绘制,很可能会造成刷新率下降,造成卡顿的现象。对于过度绘制的测试主要通过人工进行测试,也是发现应用过渡绘制的首选途径,通过打开开发者选项中的 显示GPU过度绘制。过渡绘制可以通过颜色标识,按照从好到差依次是:蓝、绿、淡红、红。

蓝色x过度绘制

绿色x过度绘制

淡红色x过度绘制

红色超过x过度绘制

避免过度绘制的方法:

去掉多余背景色,减少复杂shape使用;

避免层级叠加;

自定义 View 使用 clipRect 屏蔽被遮盖View绘制;

布局优化的其它技巧:

使用 ViewStub 标签来加载一些不常用的布局,ViewStub 是一个高效的占位符可以实现延迟初始化。

在 onDraw() 方法中避免创建大对象和其它耗时操作。

TextView 的优化,TextView中很多操作都很繁重。比如setText操作,须要设置SpanWatcher,或者要重现创建一个 SpannableString,还要依据情况又一次创建TextLayout,这些操作加起来之后令一次 setText 操作很耗时。可以通过自定义 view 的方式来优化,对于可编辑的文本,使用 DynamicLayout 来实现,对于静态文本,推荐使用StaticLayout。

课程收获

课程从布局加载、布局绘制的角度介绍了布局优化的方案,涵盖了布局优化的所有手段。既提供了获取优化指标的方式,又提供了优化的手段,非常实用。


本文链接:https://www.woshiqian.com/post/158752.html

百度分享获取地址:https://share.baidu.com/code
新产品发朋友圈编辑文字  

我是钱微信/QQ:5087088

广告位、广告合作QQ:5087088

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

       

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。