Diffing 对于复杂数据结构支持的多个视图类型展示在屏幕上, Epoxy此时是尤其有用的. 在这些场景中, 数据可能会被网络请求, 异步 Observable, 用户输入, 或者别的来源更新, 这些源会请求更
Diffing对于复杂数据结构支持的多个视图类型展示在屏幕上, Epoxy此时是尤其有用的. 在这些场景中, 数据可能会被网络请求, 异步 Observable, 用户输入, 或者别的来源更新, 这些源会请求更新 Model 并且通知适配器恰当变更. 手动追踪这些变更很困难, 且直接增加了显著的开销. 在这些场景下, 你可以充分利用Epoxy的自动 diffing 机制来减少开销, 同时也高效地更新变更的视图. EpoxyController类自动使用 diffing 机制, 并且在EpoxyAdapter类中可以作为选项开启. 追踪 Model 状态Epoxy在每个 Model 上调用equals和hashCode来判断 Model 的当前状态以及 Model 何时发生了变更. 对于每个 Model 而言, 正确地实现这些方法对于 diffing 正常工作很重要. Epoxy生成 Model 子类来避免手动实现equals和hashCode的开销. 异步支持EpoxyController支持在后台线程执行 diff 算法来提高性能. 查看这里获取更多细节. 最佳实践在使用 diffing 时, 有一些性能隐患需要明白. 首先, diffing 必须处理列表中的全部 Model, 有成百上千个 Model 的话, 可能会影响 Controller 的性能. 大多数情况下 diffing 算法线性时间执行, 但依然必须处理列表中的全部 Model. 无论如何, 项的移动很慢, 在最坏情况下, 比如洗牌列表中的全部 Model, 性能是 (n^2)/2. 其次, 每一次 diff 必须通过equals/hashCode计算 Model 的状态, 来决定项变更. 在这些实现中避免导入不必要的计算会显著地拖慢 diff. 还有, 要清楚无意间修改 Model 状态, 例如点击监听器. 举个例子, 在 Model 设置点击监听器是很普遍的做法, 监听器会在 View 绑定的时候设置. 容易犯的错误是使用匿名内部类作为点击监听器, 这会影响 Model 状态, 并且在 Model 更新或者重建的时候请求视图重新绑定. 在这个场景下可以使用DoNotHash选项(@EpoxyAttribute(DoNotHash)告知生成的 Model 将该字段从状态的计算中排除出来). 另一个常见错误是在 Model 绑定调用期间修改 Model 状态. 注意该算法 - Android支持库类DiffUtil用于在EpoxyController中执行diffing. 由于历史原因, 更早的EpoxyAdapter使用了自定义方案进行diffing. 配置有几个配置选项用来控制Epoxy的注解处理器的行为. 可用选项
控制这些选项In gradle所有的这些选项在build.gradle文件中能够设置为注解处理器选项. project.android.buildTypes.all { buildType -> buildType.javaCompileOptions.annotationProcessorOptions.arguments = [ // Validation is disabled in production to remove the runtime overhead validateEpoxyModelUsage : String.valueOf(buildType.name == 'debug'), requireHashCodeInEpoxyModels: "true", requireAbstractEpoxyModels : "true", implicitlyAddAutoModels : "true" ] } 复制代码 对于拥有许多 Model 和贡献者的大型项目, 使用这些选项尤其有用. 在这些场景下, Model拥有标准模型极大地缩减了创建和使用 Model 时的错误. In Java候选情况下, 可使用@PackageEpoxyConfig包注解为每一个包下的 Model 指定配置选项. 在该包下创建package-info.java. 不过这种方式不能修改validateEpoxyModelUsage选项. @PackageEpoxyConfig( requireAbstractModels = true, requireHashCode = true, implicitlyAddAutoModels = true ) package com.example.app; import com.airbnb.epoxy.PackageEpoxyConfig; 复制代码 如果包下没有找到配置选项, 那么来自最近父包下的配置将被使用. 如果全部父包都没有声明配置, 那么设置在build.gradle文件里面的注解处理器将被使用. 如果build.gradle文件中也没有配置, 那么将使用默认值 |
2022-04-23
2022-01-26
2021-11-15
2021-08-02
2019-12-15