最近在研究滴滴公司开源的booster框架的源码,地址:https://github.com/didi/booster
但是会有些以为,里面的代码是怎么写出来的? 有些代码确实有点看不懂,比如下面的
it.desc == "()V"
到底是怎么写出来的?
L$SHADOW_TOAST;)V
为什么要这么拼成 Landroid/widget/Toast???
这些人写代码的时候,难道是一个一个手动敲的?不会敲错吗?
我想这些这些使用asm操作java字节码的操作,肯定是能够看到java字节码,才把部分逻辑写完的。那么如何查看java字节码呢??
通过网上查询了几篇博客,大概了解了可以使用ASM Bytecode Outline插件来查看java字节码。
点击【Get】 进入下载版本页面 https://plugins.jetbrains.com/plugin/5918-asm-bytecode-outline/versions
【Settings】–>【Plugins】
点击右上角图标,选择【Install Plugn from Disk】
选择刚下好的 asm-bo-0.3.5.zip 点击 【OK】 即可安装
安装好了,点击【Restart IDE】 生效
重启Android Studio之后,就会有ASM的标志,如下所示
选择一个java文件,查看其java字节码 ,如下所示
进入java文件编辑区域,鼠标右键弹出菜单项,选择【Show Bytecode outline】
然后后面的ASM框就会显示内容,如下所示
package com.xtc.common.util;
import android.content.Context;
/**
* 尺寸转换工具
*
* Created by ouyangpeng on 2015/9/21.
*/
public class SizeConvertUtil {
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*
* @param context 上下文
* @param dp dp的值
* @return px的值
*/
public static int dpToPx(Context context, float dp) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*
* @param context 上下文
* @param px px的值
* @return dp的值
*/
public static int pxToDp(Context context, float px) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (px / scale + 0.5f);
}
/**
* 将px值转换为sp值,保证文字大小不变
*
* @param context 上下文
* @param px px的值
* @return sp的值
*/
public static int pxToSp(Context context, float px) {
//DisplayMetrics类中属性scaledDensity
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (px / fontScale + 0.5f);
}
/**
* 将sp值转换为px值,保证文字大小不变
*
* @param context 上下文
* @param sp sp的值
* @return px的值
*/
public static int spToPx(Context context, float sp) {
//DisplayMetrics类中属性scaledDensity
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (sp * fontScale + 0.5f);
}
}
// class version 51.0 (51)
// access flags 0x21
public class com/xtc/common/util/SizeConvertUtil {
// compiled from: SizeConvertUtil.java
// access flags 0x1
public ()V
L0
LINENUMBER 10 L0
ALOAD 0
INVOKESPECIAL java/lang/Object. ()V
RETURN
L1
LOCALVARIABLE this Lcom/xtc/common/util/SizeConvertUtil; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x9
public static dpToPx(Landroid/content/Context;F)I
L0
LINENUMBER 19 L0
ALOAD 0
INVOKEVIRTUAL android/content/Context.getResources ()Landroid/content/res/Resources;
INVOKEVIRTUAL android/content/res/Resources.getDisplayMetrics ()Landroid/util/DisplayMetrics;
GETFIELD android/util/DisplayMetrics.density : F
FSTORE 2
L1
LINENUMBER 20 L1
FLOAD 1
FLOAD 2
FMUL
LDC 0.5
FADD
F2I
IRETURN
L2
LOCALVARIABLE context Landroid/content/Context; L0 L2 0
LOCALVARIABLE dp F L0 L2 1
LOCALVARIABLE scale F L1 L2 2
MAXSTACK = 2
MAXLOCALS = 3
// access flags 0x9
public static pxToDp(Landroid/content/Context;F)I
L0
LINENUMBER 31 L0
ALOAD 0
INVOKEVIRTUAL android/content/Context.getResources ()Landroid/content/res/Resources;
INVOKEVIRTUAL android/content/res/Resources.getDisplayMetrics ()Landroid/util/DisplayMetrics;
GETFIELD android/util/DisplayMetrics.density : F
FSTORE 2
L1
LINENUMBER 32 L1
FLOAD 1
FLOAD 2
FDIV
LDC 0.5
FADD
F2I
IRETURN
L2
LOCALVARIABLE context Landroid/content/Context; L0 L2 0
LOCALVARIABLE px F L0 L2 1
LOCALVARIABLE scale F L1 L2 2
MAXSTACK = 2
MAXLOCALS = 3
// access flags 0x9
public static pxToSp(Landroid/content/Context;F)I
L0
LINENUMBER 44 L0
ALOAD 0
INVOKEVIRTUAL android/content/Context.getResources ()Landroid/content/res/Resources;
INVOKEVIRTUAL android/content/res/Resources.getDisplayMetrics ()Landroid/util/DisplayMetrics;
GETFIELD android/util/DisplayMetrics.scaledDensity : F
FSTORE 2
L1
LINENUMBER 45 L1
FLOAD 1
FLOAD 2
FDIV
LDC 0.5
FADD
F2I
IRETURN
L2
LOCALVARIABLE context Landroid/content/Context; L0 L2 0
LOCALVARIABLE px F L0 L2 1
LOCALVARIABLE fontScale F L1 L2 2
MAXSTACK = 2
MAXLOCALS = 3
// access flags 0x9
public static spToPx(Landroid/content/Context;F)I
L0
LINENUMBER 57 L0
ALOAD 0
INVOKEVIRTUAL android/content/Context.getResources ()Landroid/content/res/Resources;
INVOKEVIRTUAL android/content/res/Resources.getDisplayMetrics ()Landroid/util/DisplayMetrics;
GETFIELD android/util/DisplayMetrics.scaledDensity : F
FSTORE 2
L1
LINENUMBER 58 L1
FLOAD 1
FLOAD 2
FMUL
LDC 0.5
FADD
F2I
IRETURN
L2
LOCALVARIABLE context Landroid/content/Context; L0 L2 0
LOCALVARIABLE sp F L0 L2 1
LOCALVARIABLE fontScale F L1 L2 2
MAXSTACK = 2
MAXLOCALS = 3
}
package asm.com.xtc.common.util;
import java.util.*;
import org.objectweb.asm.*;
public class SizeConvertUtilDump implements Opcodes {
public static byte[] dump() throws Exception {
ClassWriter cw = new ClassWriter(0);
FieldVisitor fv;
MethodVisitor mv;
AnnotationVisitor av0;
cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, "com/xtc/common/util/SizeConvertUtil", null, "java/lang/Object", null);
cw.visitSource("SizeConvertUtil.java", null);
{
mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitLineNumber(10, l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false);
mv.visitInsn(RETURN);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLocalVariable("this", "Lcom/xtc/common/util/SizeConvertUtil;", null, l0, l1, 0);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "dpToPx", "(Landroid/content/Context;F)I", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitLineNumber(19, l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, "android/content/Context", "getResources", "()Landroid/content/res/Resources;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "android/content/res/Resources", "getDisplayMetrics", "()Landroid/util/DisplayMetrics;", false);
mv.visitFieldInsn(GETFIELD, "android/util/DisplayMetrics", "density", "F");
mv.visitVarInsn(FSTORE, 2);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLineNumber(20, l1);
mv.visitVarInsn(FLOAD, 1);
mv.visitVarInsn(FLOAD, 2);
mv.visitInsn(FMUL);
mv.visitLdcInsn(new Float("0.5"));
mv.visitInsn(FADD);
mv.visitInsn(F2I);
mv.visitInsn(IRETURN);
Label l2 = new Label();
mv.visitLabel(l2);
mv.visitLocalVariable("context", "Landroid/content/Context;", null, l0, l2, 0);
mv.visitLocalVariable("dp", "F", null, l0, l2, 1);
mv.visitLocalVariable("scale", "F", null, l1, l2, 2);
mv.visitMaxs(2, 3);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "pxToDp", "(Landroid/content/Context;F)I", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitLineNumber(31, l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, "android/content/Context", "getResources", "()Landroid/content/res/Resources;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "android/content/res/Resources", "getDisplayMetrics", "()Landroid/util/DisplayMetrics;", false);
mv.visitFieldInsn(GETFIELD, "android/util/DisplayMetrics", "density", "F");
mv.visitVarInsn(FSTORE, 2);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLineNumber(32, l1);
mv.visitVarInsn(FLOAD, 1);
mv.visitVarInsn(FLOAD, 2);
mv.visitInsn(FDIV);
mv.visitLdcInsn(new Float("0.5"));
mv.visitInsn(FADD);
mv.visitInsn(F2I);
mv.visitInsn(IRETURN);
Label l2 = new Label();
mv.visitLabel(l2);
mv.visitLocalVariable("context", "Landroid/content/Context;", null, l0, l2, 0);
mv.visitLocalVariable("px", "F", null, l0, l2, 1);
mv.visitLocalVariable("scale", "F", null, l1, l2, 2);
mv.visitMaxs(2, 3);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "pxToSp", "(Landroid/content/Context;F)I", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitLineNumber(44, l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, "android/content/Context", "getResources", "()Landroid/content/res/Resources;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "android/content/res/Resources", "getDisplayMetrics", "()Landroid/util/DisplayMetrics;", false);
mv.visitFieldInsn(GETFIELD, "android/util/DisplayMetrics", "scaledDensity", "F");
mv.visitVarInsn(FSTORE, 2);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLineNumber(45, l1);
mv.visitVarInsn(FLOAD, 1);
mv.visitVarInsn(FLOAD, 2);
mv.visitInsn(FDIV);
mv.visitLdcInsn(new Float("0.5"));
mv.visitInsn(FADD);
mv.visitInsn(F2I);
mv.visitInsn(IRETURN);
Label l2 = new Label();
mv.visitLabel(l2);
mv.visitLocalVariable("context", "Landroid/content/Context;", null, l0, l2, 0);
mv.visitLocalVariable("px", "F", null, l0, l2, 1);
mv.visitLocalVariable("fontScale", "F", null, l1, l2, 2);
mv.visitMaxs(2, 3);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "spToPx", "(Landroid/content/Context;F)I", null, null);
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitLineNumber(57, l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, "android/content/Context", "getResources", "()Landroid/content/res/Resources;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "android/content/res/Resources", "getDisplayMetrics", "()Landroid/util/DisplayMetrics;", false);
mv.visitFieldInsn(GETFIELD, "android/util/DisplayMetrics", "scaledDensity", "F");
mv.visitVarInsn(FSTORE, 2);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLineNumber(58, l1);
mv.visitVarInsn(FLOAD, 1);
mv.visitVarInsn(FLOAD, 2);
mv.visitInsn(FMUL);
mv.visitLdcInsn(new Float("0.5"));
mv.visitInsn(FADD);
mv.visitInsn(F2I);
mv.visitInsn(IRETURN);
Label l2 = new Label();
mv.visitLabel(l2);
mv.visitLocalVariable("context", "Landroid/content/Context;", null, l0, l2, 0);
mv.visitLocalVariable("sp", "F", null, l0, l2, 1);
mv.visitLocalVariable("fontScale", "F", null, l1, l2, 2);
mv.visitMaxs(2, 3);
mv.visitEnd();
}
cw.visitEnd();
return cw.toByteArray();
}
}
// class version 51.0 (51)
// access flags 0x21
public class com/xtc/common/util/SizeConvertUtil {
@groovyx.ast.bytecode.Bytecode
public void () {
aload 0
INVOKESPECIAL java/lang/Object. ()V
return
}
@groovyx.ast.bytecode.Bytecode
public static int dpToPx(android.content.Context a,float b) {
aload 0
INVOKEVIRTUAL android/content/Context.getResources ()Landroid/content/res/Resources;
INVOKEVIRTUAL android/content/res/Resources.getDisplayMetrics ()Landroid/util/DisplayMetrics;
getfield 'android/util/DisplayMetrics.density','F'
fstore 2
fload 1
fload 2
fmul
ldc 0.5f
fadd
f2i
ireturn
}
@groovyx.ast.bytecode.Bytecode
public static int pxToDp(android.content.Context a,float b) {
aload 0
INVOKEVIRTUAL android/content/Context.getResources ()Landroid/content/res/Resources;
INVOKEVIRTUAL android/content/res/Resources.getDisplayMetrics ()Landroid/util/DisplayMetrics;
getfield 'android/util/DisplayMetrics.density','F'
fstore 2
fload 1
fload 2
fdiv
ldc 0.5f
fadd
f2i
ireturn
}
@groovyx.ast.bytecode.Bytecode
public static int pxToSp(android.content.Context a,float b) {
aload 0
INVOKEVIRTUAL android/content/Context.getResources ()Landroid/content/res/Resources;
INVOKEVIRTUAL android/content/res/Resources.getDisplayMetrics ()Landroid/util/DisplayMetrics;
getfield 'android/util/DisplayMetrics.scaledDensity','F'
fstore 2
fload 1
fload 2
fdiv
ldc 0.5f
fadd
f2i
ireturn
}
@groovyx.ast.bytecode.Bytecode
public static int spToPx(android.content.Context a,float b) {
aload 0
INVOKEVIRTUAL android/content/Context.getResources ()Landroid/content/res/Resources;
INVOKEVIRTUAL android/content/res/Resources.getDisplayMetrics ()Landroid/util/DisplayMetrics;
getfield 'android/util/DisplayMetrics.scaledDensity','F'
fstore 2
fload 1
fload 2
fmul
ldc 0.5f
fadd
f2i
ireturn
}
}
从上面的ASM Bytecode Outline 插件我们就可以看到对应的字节码了,对比源文件,大概能够看懂一些些了。
具体关于字节码的相关知识点,请参考下面的链接
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:https://blog.csdn.net/qq446282412/article/details/100566678
☞ 本人QQ: 3024665621
☞ QQ交流群: 123133153
☞ github.com/ouyangpeng
☞ [email protected]