http://ift.tt/2GampFj
内部类
内部类的smali特点,就是会在外部类的后面加一个$符号,然后是内部类名,如
MainActivity$Myinner
如下面的例子
java:
class MyInner{
int mInt =1;
public void Test(){
System.out.println(mInt);
}
}
.class Lscience/cole/myapplication/MainActivity$MyInner;
.super Ljava/lang/Object;
.source "MainActivity.java"
# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
value = Lscience/cole/myapplication/MainActivity;
.end annotation
.annotation system Ldalvik/annotation/InnerClass;
accessFlags = 0x0
name = "MyInner"
.end annotation
# instance fields
.field mInt:I
.field final synthetic this$0:Lscience/cole/myapplication/MainActivity;
# direct methods
#可以看到,在调用内部类的构造函数的时候,会传入外部类的指针
.method constructor <init>(Lscience/cole/myapplication/MainActivity;)V
.locals 1
#这吧外部类的对象的指针给了p1,让内部类知道是谁调用的
.param p1, "this$0" # Lscience/cole/myapplication/MainActivity;
.prologue
.line 19
iput-object p1, p0, Lscience/cole/myapplication/MainActivity$MyInner;->this$0:Lscience/cole/myapplication/MainActivity;
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
.line 20
const/4 v0, 0x1
iput v0, p0, Lscience/cole/myapplication/MainActivity$MyInner;->mInt:I
return-void
.end method
# virtual methods
#下面就是自定义的函数,其实跟别的是函数是一样的
.method public Test()V
.locals 2
.prologue
.line 22
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
#将p0寄存器中指向mInt的实例引用存入到v1寄存器中
iget v1, p0, Lscience/cole/myapplication/MainActivity$MyInner;->mInt:I
invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(I)V
.line 23
return-void
.end method
这里需要注意的就是,在调用内部类的构造的时候,会把外部类对象指针作为参数给构造函数,看到有这个特征的就是内部类无疑了
匿名内部类
匿名内部类的smali特点,就是会在外部类的后面加一个$符号,然后是一个编号,如
MainActivity$1
如下面的例子
Button btn =(Button)findViewById(R.id.btn_test);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
System.out.println("test 匿名内部类");
}
});
smali:
#外部在调用匿名内部类的时候,MainActivity$1 就是匿名外部类的类名
new-instance v1, Lscience/cole/myapplication/MainActivity$1;
#匿名内部类在构造的时候,还是会传入外部类的指针
invoke-direct {v1, p0}, Lscience/cole/myapplication/MainActivity$1;-><init>(Lscience/cole/myapplication/MainActivity;)V
invoke-virtual {v0, v1}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V
内部类访问外部类的私有变量
内部类访问外部类的共有成员时,与在外部类中是一样的
内部类访问外部类的私有
成员时,在内部类会生成类似access$100
这种方法来回去外部类的私有变量
java:
public class MainActivity extends AppCompatActivity {
private int nNumber =2;
public int nNumber2= 3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 测试
MyInner my =new MyInner();
my.Test();
}
class MyInner{
int mInt ;
public void Test(){
mInt = nNumber2;
mInt = nNumber;
}
}
}
smali:
# virtual methods
.method public Test()V
.locals 1
.prologue
.line 34
iget-object v0, p0, Lscience/cole/myapplication/MainActivity$MyInner;->this$0:Lscience/cole/myapplication/MainActivity;
iget v0, v0, Lscience/cole/myapplication/MainActivity;->nNumber2:I
iput v0, p0, Lscience/cole/myapplication/MainActivity$MyInner;->mInt:I
.line 35
iget-object v0, p0, Lscience/cole/myapplication/MainActivity$MyInner;->this$0:Lscience/cole/myapplication/MainActivity;
#关键的就是这个地方,内部类访问外部类的私有变量的时候,会产生一个access$xxxxx
# getter for: Lscience/cole/myapplication/MainActivity;->nNumber:I
invoke-static {v0}, Lscience/cole/myapplication/MainActivity;->access$000(Lscience/cole/myapplication/MainActivity;)I
move-result v0
iput v0, p0, Lscience/cole/myapplication/MainActivity$MyInner;->mInt:I
.line 36
return-void
.end method
外部类访问内部类的私有变量
当外部类访问内部类的私有
变量的时候,会产生类似access$002
这种的方法,来获取变量的值
java:
public class MainActivity extends AppCompatActivity {
int number;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 测试
MyInner my =new MyInner();
number =my.mInt;
}
class MyInner{
private int mInt=5 ;
}
}
smali:
.line 19
.local v0, "my":Lscience/cole/myapplication/MainActivity$MyInner;
# getter for: Lscience/cole/myapplication/MainActivity$MyInner;->mInt:I
#外部类调用内部类的私有属性
invoke-static {v0}, Lscience/cole/myapplication/MainActivity$MyInner;->access$000(Lscience/cole/myapplication/MainActivity$MyInner;)I
move-result v1
iput v1, p0, Lscience/cole/myapplication/MainActivity;->number:I
iput v1, p0, Lscience/cole/myapplication/MainActivity;->number:I
The post # java语言反编译 smali 汇编基础语法(5)之内部类以及内部类的访问 appeared first on cole.
http://ift.tt/2DyyCGb Smali, smali January 24, 2018 at 03:22PM
评论
发表评论