AGP 升级问题续集来了,不看血亏,真是骚,kotlin集合操作符

本文详细分析了Android Gradle Plugin(AGP)不同版本中R类的字节码差异,探讨了ASM与javac在生成R类时的内存占用和效率问题。通过对AGP 3.1.2、3.5.0和4.1.0的R类字节码进行反编译和对比,发现ASM生成的R类更为“紧凑”,减少了静态代码块的使用,从而提升了资源容纳能力。随着AGP版本升级,ASM的优化使得library module的R类可容纳资源数量显著增加,对于大型项目具有积极影响。
摘要由CSDN通过智能技术生成

flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL

ConstantValue: int 2130837504

}

InnerClasses:

public static final #7= #2 of #6; //id=class cn/yan/libr/R$id of class cn/yan/libr/R

反编译主模块产物中 ASM 生成的R.jar中主模块自己合并的属性成员 final 且有明确初值的R$id.class也是 17,与上面一样,所以不再给出。

可以看到,由于我们 demo 中主 module 无额外的 id 资源,所以子 module 里通过 ASM 生成的 R$id.class 的 class 常量池占用个数为 17,主 module 里也是 17。

AGP3.5.0 的 R 字节码

反编译子模块产物中 ASM 生成的R.jar中非 final 且属性成员无明确初值的R$id.class为例(其他 R class 雷同):

yandeMacBook-Pro:libr yan$ javap -v R$id.class

Classfile /Users/yan/work/tmp/TestR/libR/build/intermediates/compile_only_not_namespaced_r_class_jar/debug/cn/yan/libr/R$id.class

Last modified 2020-11-8; size 241 bytes

MD5 checksum 4b6b893cff236cdc445f392e0ce41a2b

public final class cn.yan.libr.R$id

minor version: 0

major version: 52

flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER

//重点!!!class的常量池,这里总共占用#17个

Constant pool:

#1 = Utf8 cn/yan/libr/R$id

#2 = Class #1 // cn/yan/libr/R$id

#3 = Utf8 java/lang/Object

#4 = Class #3 // java/lang/Object

#5 = Utf8 cn/yan/libr/R

#6 = Class #5 // cn/yan/libr/R

#7 = Utf8 id

#8 = Utf8 test_layout

#9 = Utf8 I

#10 = Integer 2131427329

#11 = Utf8

#12 = Utf8 ()V

#13 = NameAndType #11:#12 // “”😦)V

#14 = Methodref #4.#13 // java/lang/Object.""😦)V

#15 = Utf8 ConstantValue

#16 = Utf8 Code

#17 = Utf8 InnerClasses

{

public static int test_layout;

descriptor: I

flags: ACC_PUBLIC, ACC_STATIC

ConstantValue: int 2131427329

}

InnerClasses:

public static final #7= #2 of #6; //id=class cn/yan/libr/R$id of class cn/yan/libr/R

反编译主模块产物中 javac 生成的依赖子模块自己的属性成员 final 且有明确初值的R$id.class为例(其他 R class 雷同):

//【工匠若水 加微信 yanbo373131686 联系我,关注微信公众号:码农每日一题 未经允许严禁转载 https://blog.csdn.net/yanbober】

yandeMacBook-Pro:libr yan$ javap -v R$id.class

Classfile /Users/yan/work/tmp/TestR/app/build/intermediates/javac/debug/classes/cn/yan/libr/R$id.class

Last modified 2020-11-8; size 368 bytes

MD5 checksum 18fbba9c0a1f51068cbd984810e53eac

Compiled from “R.java”

public final class cn.yan.libr.R$id

minor version: 0

major version: 52

flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER

//重点!!!class的常量池,这里总共占用#23个

Constant pool:

#1 = Methodref #3.#19 // java/lang/Object.""😦)V

#2 = Class #21 // cn/yan/libr/R$id

#3 = Class #22 // java/lang/Object

#4 = Utf8 test_layout

#5 = Utf8 I

#6 = Utf8 ConstantValue

#7 = Integer 2130837504

#8 = Utf8

#9 = Utf8 ()V

#10 = Utf8 Code

#11 = Utf8 LineNumberTable

#12 = Utf8 LocalVariableTable

#13 = Utf8 this

#14 = Utf8 id

#15 = Utf8 InnerClasses

#16 = Utf8 Lcn/yan/libr/R$id;

#17 = Utf8 SourceFile

#18 = Utf8 R.java

#19 = NameAndType #8:#9 // “”😦)V

#20 = Class #23 // cn/yan/libr/R

#21 = Utf8 cn/yan/libr/R$id

#22 = Utf8 java/lang/Object

#23 = Utf8 cn/yan/libr/R

{

public static final int test_layout;

descriptor: I

flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL

ConstantValue: int 2130837504

}

SourceFile: “R.java”

InnerClasses:

public static final #14= #2 of #20; //id=class cn/yan/libr/R$id of class cn/yan/libr/R

反编译主模块产物中 javac 生成的主模块自己合并的属性成员 final 且有明确初值的R$id.class也是 23,与上面一样,所以不再给出。

可以看到,由于我们 demo 中主 module 无额外的 id 资源,所以子 module 里通过 ASM 生成的 R$id.class 的 class 常量池占用个数为 17,而主 module 里是先生成R.java然后通过 javac 编译生成的R.class,所以常量池占用个数变为了 23。我们类成员属性只有一个,ASM 和 javac 的 class 就差了 6 个,至于为什么后面分析,先继续。

AGP3.1.2 的 R 字节码

反编译子模块产物中 javac 生成的非 final 且属性成员无明确初值的R$id.class为例(其他 R class 雷同):

yandeMacBook-Pro:libr yan$ javap -v R$id.class

Classfile /Users/yan/work/tmp/TestR/libR/build/intermediates/classes/debug/cn/yan/libr/R$id.class

Last modified 2020-11-8; size 409 bytes

MD5 checksum 7ff99374e393fa8059ab57413e787968

Compiled from “R.java”

public final class cn.yan.libr.R$id

minor version: 0

major version: 52

flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER

//重点!!!class的常量池,这里总共占用#25个

Constant pool:

#1 = Methodref #5.#20 // java/lang/Object.""😦)V

#2 = Integer 2131492865

#3 = Fieldref #4.#21 // cn/yan/libr/R$id.test_layout:I

#4 = Class #23 // cn/yan/libr/R$id

#5 = Class #24 // java/lang/Object

#6 = Utf8 test_layout

#7 = Utf8 I

#8 = Utf8

#9 = Utf8 ()V

#10 = Utf8 Code

#11 = Utf8 LineNumberTable

#12 = Utf8 LocalVariableTable

#13 = Utf8 this

#14 = Utf8 id

#15 = Utf8 InnerClasses

#16 = Utf8 Lcn/yan/libr/R$id;

#17 = Utf8

#18 = Utf8 SourceFile

#19 = Utf8 R.java

#20 = NameAndType #8:#9 // “”😦)V

#21 = NameAnd

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值