Android(安卓)assert 机制
16lz
2021-01-26
java 中 可以使用assert语法来进行一些判断检,但是 android上 assert似乎不生效, 这是为什么呢。
在将java source code编译成class文件的过程中,如果一个类中使用了assert语法,那么class文件中会生成一个static field。
final static synthetic Z $assertionsDisabled
在类的静态初始化函数,会生成以下代码
static ()V L0 LINENUMBER 20 L0 LDC Lorg/chromium/base/JavaExceptionReporter;.class INVOKEVIRTUAL java/lang/Class.desiredAssertionStatus ()Z IFNE L1 ICONST_1 GOTO L2 L1 FRAME SAME ICONST_0 L2 FRAME SAME1 I PUTSTATIC org/chromium/base/JavaExceptionReporter.$assertionsDisabled : Z RETURN
会先判断Class.desiredAssertionStatus()的返回值,如果是false, 设置assertionsDisabled为false。
android中 Class.desiredAssertionStatus() 的定义
public boolean desiredAssertionStatus() { return false;}
所以$assertionsDisabled会被设置为true。
真正使用assert的地,会被替换为
L0 LINENUMBER 55 L0 GETSTATIC org/chromium/base/JavaExceptionReporter.$assertionsDisabled : Z IFNE L1 INVOKESTATIC "assert method"Z IFNE L1 NEW java/lang/AssertionError DUP INVOKESPECIAL java/lang/AssertionError. ()V ATHROW L1 LINENUMBER 59 L1
如果$assertionsDisabled 为false,则会先判断assert后面的值,如果是true,则会抛出 AssertionError异常,否则就执行后面的代码。
所以在Android要使assert生效,有两种方法:
-
adb shell setprop debug.assert 1
(只对dalvik虚拟机生,对art虚拟机不生效!) - 使用字节码修改工具,比如asm,用以下代码将赋值
$assertionsDisabled
的地方替换成POP 指令。
@Override public void visitFieldInsn(int opcode, String owner, String name, String desc) { if (opcode == Opcodes.PUTSTATIC && name.equals("$assertionsDisabled")) { super.visitInsn(Opcodes.POP); // enable assert } }
更多相关文章
- 打开和关闭WIFI 的代码出现了问题 android
- MPAndroidChart中使用 LineChart 踩得坑!
- Android--Activity运用实验
- android 1.6 launcher研究之修改worksapce上的屏数
- Android(安卓)Studio中读取文本文件内容方法
- android EditText 限制输入大小写,大写转小写
- Android包管理机制(二)PackageInstaller安装APK
- Channel is unrecoverably broken and will be disposed!
- 图片阴影