抖音字体大小设置方法安卓 抖音字体大小设置方法( 七 )


首先通过反射获取待解析对象的所有 Field,并逐个读取去读取它们的注解,生成一个从 serializeName 到 Filed 映射 map;解析过程中,通过读取到的 serializeName,到生成的 map 中找到对应的 Filed 信息,然后根据 Filed 的数据类型采用特定类型的方式进行解析,然后通过反射方式进行赋值 。
因此对于 Gson 解析耗时优化的核心就是减少反射,这里具体介绍一下抖音中使用到的一些优化方案 。
自定义 TypeAdapter 优化
通过对 Gson 的源码分析,我们知道 Gson 的解析采用的是责任链的形式,如果在 ReflectiveTypeAdapterFactory 之前已经有 TypeAdapterFactory 能够处理某个 Class,那么它是不会执行到 ReflectiveTypeAdapterFactory 的,而 Gson 框架又是支持注入自定义的 TypeAdapterFactory 的,因此我们的一种优化方案就是注入一个自定义的 TypeAdapterFactory 去优化这个解析过程 。
这个自定义 TypeAdapterFactory 会在编译期为每个待优化的 Class 生成一个自定义的 TypeAdapter,在这个 TypeAdapter 中会为 Class 的每个字段生成相关的解析代码,以达到避免反射的目的 。

抖音字体大小设置方法安卓 抖音字体大小设置方法


生成自定义 TypeAdapter 过程中的字节码处理,我们采用了抖音团队开源的字节码处理框架 Bytex(https://github.com/bytedance/ByteX/blob/master/README_zh.md),具体的实现过程如下:
配置待优化 Class:在开发阶段,通过注解、配置文件的方式对我们需要优化的 Class 进行加白;收集待优化 Class 信息:开始编译后,我们从配置文件中读取通过配置文件配置 Class;在遍历工程中所有的 class 的 traverse 阶段,我们通过 ASM 提供的 ClassVisitor 去读取通过注解配置的 Class 。对于所有需要优化的 Class,我们利用 ClassVisitor 的 visitField 方法收集当前 Class 的所有 Filed 信息;生成自定义 TypeAdapter 和 TypeAdapterFactory:在 trasform 阶段,我们利用收集到的 Class 和 Field 信息生成自定义的 TypeAdapter 类,同时生成创建这些 TypeAdapter 的自定义 TypeAdapterFactory;public class GsonOptTypeAdapterFactory extends BaseAdapterFactory {
protected BaseAdapter createTypeAdapter(String var1) {
switch(var1.hashCode()) {
case -1939156288:
if (var1.equals("xxx/xxx/gsonopt/model/Model1")) {
return new TypeAdapterForModel1(this.gson);
}
break;
case -1914731121:
if (var1.equals("xxx/xxx/gsonopt/model/Model2")) {
return new TypeAdapterForModel2(this.gson);
}
break;
return null;
}
}
public abstract class TypeAdapterForModel1 extends BaseTypeAdapter {
protected void setFieldValue(String var1, Object var2, JsonReader var3) {
Object var4;
switch(var1.hashCode()) {
case 110371416:
if (var1.equals("field1")) {
var4 = this.gson.getAdapter(String.class).read(var3);
((Model1)var2).field1 = (String)var4;
return true;
}
break;
case 1223751172:
if (var1.equals("filed2")) {
var4 = this.gson.getAdapter(String.class).read(var3);
((Model1)var2).field2 = (String)var4;
return true;
}
}
return false;
}
}
优化 ReflectiveTypeAdapterFactory 实现
上面这种自定义 TypeAdapter 的方式可以对 Gson 的首次解析耗时优化 70%左右,但是这个方案需要在编译期增加解析代码,会增加包体积,具有一定的局限性,为此我们也尝试了对 Gson 框架的实现进行了优化,为了降低接入成本我们通过修改字节码的方式去修改 ReflectiveTypeAdapterFactory 的实现 。
原始的 ReflectiveTypeAdapterFactory 在进行实际数据解析之前,会首先去反射 Class 的所有字段信息,再进行解析,而在实际解析过程中并不是所有的字段都是会使用到的,以下面的 Person 类为例,在进行 Person 解析之前,会对 Person、Hometown、Job 这三个类都进行解析,但是实际输入可能只是简单的 name,这种情况下对于 Hometown、Job 的解析就是完全没有必要的,如果 Hometown、Job 类的实现比较复杂,这将导致较多不必要的时间开销 。

推荐阅读