我们知道android中java文件先被编译成由java字节码组成的class文件,最终会被编译打包成.dex文件,文件中是可以运行于dalvik虚拟机的字节码。这些字节码不具有可读性, 可以从这些字节码反编译得到的更具有可读性的smali文件。
具体方式可以参阅开源项目smali,下面是一些smali的语法
- 类型标记,和jni中的表示是一样的
java中的类型 : smali中对应的表示
boolean : Z
char : c
byte : B
short : S
int : I
long : J
float : F
double : D
L表示某个类,例如,Ljava/lang/String;
表示String类
[ 表示数组,例如,[Ljava/lang/String;
表示String数组
- 方法的参数及局部变量
以p开头的代表参数,p0代码this,p1,p2,p3代表方法的第一、第二、第三个参数
以v开头的代表局部变量,也是从0开始计数的
- get/put 实例变量的方式
iget/iput 获取/写入实例变量
iget-object/iput-object 获取/写入实例对象
例如:
iget-boolean v0(获取后放在哪里), p0(从哪里获取), Lcom/gotokeep/keep/training/ijk/TextureVideoViewWIthIjk;->w:Z// 获取w的值,放入v0中
iget-object v2, p0, Lcom/gotokeep/keep/training/ijk/TextureVideoViewWIthIjk;->c:Landroid/net/Uri;
iput-object v0, p0,
Lcom/gotokeep/keep/training/ijk/TextureVideoViewWIthIjk;->b:Ljava/lang/String; //把v0的值写入b中
- 获取和写入static变量的方式
sget/sput 获取/写入static变量
sget-object/sput-object 获取/写入static对象
例如:
sput v0, Lcom/tencent/android/tpush/service/d/e;->a:I
sput-boolean v0, Lcom/gotokeep/keep/magic/v;->b:Z
sput-short v0, Lcom/tencent/android/tpush/stat/c;->k:S
sput-object v1, Lcom/gotokeep/keep/utils/n/at;->f:Ljava/lang/String;
sget-boolean v0, Lcom/gotokeep/keep/training/ijk/a;->a:Z //因为是sget,所以就不需要再写通常会写的用于标明从哪里获取的p0了
- 方法调用
invoke-virture 是调用父类中的方法,例如:
invoke-virtual {v0}(在v0上调用,没有参数), Ljava/lang/Long;->longValue()J
再比如:
iget-object v0, p0, Lcom/gotokeep/keep/activity/register/VideoWelcomeActivity;->videoView:Landroid/widget/VideoView; // 获取VideoWelcomeActivity的VideoView,放在v0中
invoke-static {p0}, Lcom/gotokeep/keep/activity/register/ak;->a(Lcom/gotokeep/keep/activity/register/VideoWelcomeActivity;)Landroid/media/MediaPlayer$OnErrorListener; // 调用ak的static方法,获取一个OnErrorListener
move-result-object v1 // 将结果放在v1中
invoke-virtual {v0, v1}, Landroid/widget/VideoView;->setOnErrorListener(Landroid/media/MediaPlayer$OnErrorListener;)V // 在v0上调用setOnErrorListener,参数是v1中存放的OnErrorListener
其它的方法方式还有:
invoke-direct 调用类中直接定义的方法
invoke-interface
invoke-static 调用static方法
例如:
invoke-static {v1, v2, v0}, Lcom/gotokeep/keep/domain/c/c;->onEvent(Landroid/content/Context;Ljava/lang/String;Ljava/util/Map;)V