Android 声明性布局Compose预研

背景

一些问题

  • 命令式UI痛点一
    在android发展的长河中,android的视图层次结构一直是一种多叉树的结构,创建过程是一种命令方式呈现应用界面。其中xml布局的读取解析,不仅会造成io性能消耗和反射创建标签对于的view造成的性能消耗。

    不仅如此,这种命令形式下,会提高视图出错的可能性,体现在多视图更新上,会有遗漏操作或者更新命令冲突的情况。

  • MVVM+Databinding
    当然,在使用MVVM+Databinding架构下能帮忙自动执行布局和数据绑定和更新,达成一致性。

    但是MVVM+Databinding架构的局限性也存在,一是通过AOP注解会大大增加编译时间、二是发生问题不好定位、三是不适合多变业务和协同开发。

  • 命令式UI痛点二
    除去命令形式下出错率高,还有一个难题:视图变化导致部分视图树或者整颗的重新绘制。例如,某项更新造成一个view组件从视图树中移除,就会造成视图树的重新绘制,成本昂贵啊。

  • flutter的出现
    后来,Google推出了flutter语言,新一代跨平台UI组件的诞生。全新的声明式编程的组件,同时也是响应式框架的体现(声明式UI式让开发人员描述当前的UI状态,并将转移给框架执行)。同时,也能解决上面几个问题:io和反射的性能消耗、视图与数据的绑定、视图变化导致重绘的开销。(理解flutter的三颗树原理和组件的颗粒度 来看上面的难题是否解决)

    flutter的确是一个可行方案,我们的项目也是渐进方式引入Flutter,选了几个小组件来编写。目前局限性只是在社区不成熟(这个后面会好起来的)、混合开发脱离不了原生。混合开发的疼的是,对于大型项目已经有很多成熟的通用组件,导致flutter组件调用时,会有大量的通道代码和交互代码,还有就是一些原生的基础能力支持。目前还是将flutter当作一个UI组件使用了,高性能、高流畅度还是挺香的。

  • Compose的出现
    现在,google有开发一个新能力,Jetpack Compose,是一个适用于 Android 的新式声明性界面工具包。Compose 提供声明性 API,让你可在不以命令方式改变前端视图的情况下呈现应用界面,从而使编写和维护应用界面变得更加容易。此术语需要一些解释说明,它的含义对应用设计非常重要。

    其实他跟flutter很像,其次kotlin和dart也有点类似。当然,它也解决上面那命令式的几个痛点问题,但是它没有flutter的性能好(flutter部分性能优势是来自架构层面的)。上面说的flutter的痛点问题,混合开发不够友好。其实flutter和Compose不在一个竞争纬度上,但是我个人理解的是,Compose能解决一些UI组件的问题,跟flutter一样,虽然性能不及flutter,但是本身就是原生代码,就不存在混合开发的难点了。

    其他优势,可以先看下声明性范式转变理解重组这个概念

需求

我们的需求很简单,提升页面的绘制速度和解决布局变化的重绘问题。

测试

首先我的测量工具是用addOnFrameMetricsAvailableListener方法实现的:可能不精准。测试环境:小米5手机。

 window?.addOnFrameMetricsAvailableListener(Window.OnFrameMetricsAvailableListener {
    window, frameMetrics, dropCountSinceLastInvocation ->
            Log.v("test","measure + layout=${frameMetrics.getMetric(FrameMetrics.LAYOUT_MEASURE_DURATION)/1000000}, " +
                    "    delay=${frameMetrics.getMetric(FrameMetrics.UNKNOWN_DELAY_DURATION)/1000000}, " +
                    "    anim=${frameMetrics.getMetric(FrameMetrics.ANIMATION_DURATION)/1000000}," +
                    "    touch=${frameMetrics.getMetric(FrameMetrics.INPUT_HANDLING_DURATION)/1000000}, " +
                    "    draw=${frameMetrics.getMetric(FrameMetrics.DRAW_DURATION)/1000000}, " +
                    "    total=${frameMetrics.getMetric(FrameMetrics.LAYOUT_MEASURE_DURATION)/1000000}")

        }, Handler())

然后第二种测量方式是adb测量:adb shell am start -W packagename/packagename.MainActivity
第三种测量方式,最正常的打点:onCreate和onResume 时差

文本测试

先测试单组件的测试:

原生

代码如下:

<TextView 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:padding="16dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="现在,google有开发一个新能力,Jetpack Compose,是一个适用于 Android 的新式声明性界面工具包。*Compose 提供声明性 API,让你可在不以命令方式改变前端视图的情况下呈现应用界面,从而使编写和维护应用界面变得更加容易。此术语需要一些解释说明,它的含义对应用设计非常重要。*其实他跟flutter很像,其次kotlin和dart也有点类似。当然,它也解决上面那命令式的几个痛点问题,但是它没有flutter的性能好(flutter部分性能优势是来自架构层面的)。上面说的flutter的痛点问题,混合开发不够友好。其实flutter和Compose不在一个竞争纬度上,但是我个人理解的是,Compose能解决一些UI组件的问题,跟flutter一样,虽然性能不及flutter,但是本身就是原生代码,就不存在混合开发的难点了。"
    android:textColor="#000"
    android:textSize="20dp" />

多次测试原生的单组件下:

  • addOnFrameMetricsAvailableListener 测量下measure + layout=0, delay=2, anim=0, touch=0, draw=5, total=0
  • adb测试下:ThisTime: 470 TotalTime: 849 WaitTime: 876
  • 打点测试下:执行间隔为:25ms
Compose

测试代码如下:


@Composable
fun Greeting(name: String) {
   
    Text("现在,google有开发一个新能力,Jetpack Compose,是一个适用于 Android 的新式声明性界面工具包。*Compose 提供声明性 API,让你可在不以命令方式改变前端视图的情况下呈现应用界面,从而使编写和维护应用界面变得更加容易。此术语需要一些解释说明,它的含义对应用设计非常重要。* \n" +
            "\n" +
            "\t其实他跟flutter很像,其次kotlin和dart也有点类似。当然,它也解决上面那命令式的几个痛点问题,但是它没有flutter的性能好(flutter部分性能优势是来自架构层面的)。上面说的flutter的痛点问题,混合开发不够友好。其实flutter和Compose不在一个
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值