1.内部类:一个包含简单的匿名内部类的代码:
public class EventQs extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 获取应用程序中的bn按钮
Button bn = (Button) findViewById(R.id.bn);
// 为按钮绑定事件监听器。
bn.setOnClickListener(new MyClickListener()); // ①
}
// 定义一个单击事件的监听器
class MyClickListener implements View.OnClickListener
{
// 实现监听器类必须实现的方法,该方法将会作为事件处理器
@Override
public void onClick(View v)
{
EditText txt = (EditText) findViewById(R.id.txt);
txt.setText("bn按钮被单击了!");
}
}
}
在EventQs 的smali的代码中 会包含这样的注释:
# annotations
.annotation system Ldalvik/annotation/MemberClasses;
value = {
Lorg/crazyit/event/EventQs$MyClickListener;
}
.end annotation
MemberClasses 为内部类,他代表这该类中内部类的列表,其中value中就包含了一个内部类MyClickListener
而内部类的反编译代码中包含的注释也说明自身是一个内部类。
EventQs$MyClickListener.smali:
# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
value = Lorg/crazyit/event/EventQs;
.end annotation
.annotation system Ldalvik/annotation/InnerClass;
accessFlags = 0x0
name = "MyClickListener"
.end annotation
EnclosingClass注解表明MainActivity$SNChecker作用于一个类,注解的value表明这个类是MainActivity。在EnclosingClass注解的下面是InnerClass,它表明自身是一个内部类,其中的accessFlags访问标志是一个枚举值
public class ViewSwitcherTest extends Activity
{
public static class DataItem
{
// 应用程序名称
public String dataName;
// 应用程序图标
public Drawable drawable;
}
ArrayList<DataItem> items = new ArrayList<DataItem>();
};
在ViewSwitcherTest 中内部类对应的代码 使用注释类来表达
# annotations
.annotation system Ldalvik/annotation/MemberClasses;
value = {
Lorg/crazyit/ui/ViewSwitcherTest$DataItem;
}
.end annotation
MemberClasses注解是一个系统注解,作用是为父类提供一个内部类列表
而在ViewSwitcherTest$DataItem中自身的类申明为:
# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
value = Lorg/crazyit/ui/ViewSwitcherTest;
.end annotation
.annotation system Ldalvik/annotation/InnerClass;
accessFlags = 0x9
name = "DataItem"
.end annotation
EnclosingClas表示DataItem作用于ViewSwitcherTest。下面的InnerClass表明他是一个子类,该子类的名字为DataItem。
利用内部类 创建的ArrayList对象:ArrayList<DataItem> items = new ArrayList<DataItem>();
.field private items:Ljava/util/ArrayList;
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/util/ArrayList",
"<",
"Lorg/crazyit/ui/ViewSwitcherTest$DataItem;",
">;"
}
.end annotation
.end field
2.泛型
Class<?>[] claszzs={PreferenceActivityTest.class,ExpandableListActivityTest.class};其代码为:实例字段,其中?变成了*
# instance fields
.field claszzs:[Ljava/lang/Class;
.annotation system Ldalvik/annotation/Signature;
value = {
"[",
"Ljava/lang/Class",
"<*>;"
}
.end annotation
.end field
3. 判断是否为指定类的实例if (!(activity instanceof Callbacks))
其反编译代码:
instance-of v0, p1, Lcom/example/fargmenttest2/BookListFragment$Callbacks;
判断p1是否是其后的类的实例(也可以是接口)如果是返回非0值给v0 否则返回0
4.异常
throw new IllegalStateException("BookListFargment所在的activity必须实现callbacks接口!");
反编译代码:
new-instance v0, Ljava/lang/IllegalStateException;
const-string v1, "BookListFargment\u6240\u5728\u7684activity\u5fc5\u987b\u5b9e\u73b0callbacks\u63a5\u53e3\uff01"
invoke-direct {v0, v1}, Ljava/lang/IllegalStateException;-><init>(Ljava/lang/String;)V
throw v0
5.返回值
protected ArrayList<Map<String,String>> converCurrsorTolist(Cursor cursor)
{
}
反编译代码:
.method protected converCurrsorTolist(Landroid/database/Cursor;)Ljava/util/ArrayList;
.locals 4
.parameter "cursor"
.annotation system Ldalvik/annotation/Signature;
value = {
"(",
"Landroid/database/Cursor;",
")",
"Ljava/util/ArrayList",
"<",
"Ljava/util/Map",
"<",
"Ljava/lang/String;",
"Ljava/lang/String;",
">;>;"
}
.end annotation
.prologue
.end method
6.getMethod的 Class...<?> parameterTypes参数
函数原型:public Method getMethod (String name, Class...<?> parameterTypes)
parameterTypes参数实际上是Class []类型。
源代码如下:
Method method = Class.forName( "android.os.ServiceManager").getMethod("getService", String.class);
反编译代码:
const-string v4, "android.os.ServiceManager"
.line 63
invoke-static {v4}, Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;
move-result-object v4
.line 65
const-string v5, "getService"
const/4 v6, 0x1
new-array v6, v6, [Ljava/lang/Class;
const/4 v7, 0x0
const-class v8, Ljava/lang/String;
aput-object v8, v6, v7
@代码中是new Class[]{String.class},其效果等于源代码中的String.class
.line 64
invoke-virtual {v4, v5, v6}, Ljava/lang/Class;->getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
move-result-object v2
.line 67
.local v2, method:Ljava/lang/reflect/Method;
7.静态方法中没有this指针,也就是p0不再是this指针,而是第一个参数
.method public static hookMethod(Ljava/lang/Class;Ljava/lang/reflect/Constructor;Lcom/saurik/substrate/MS$MethodAlteration;)V
.locals 0
.parameter "clazz" //P0
.parameter "member" //P1
.parameter //P2
.annotation system Ldalvik/annotation/Signature;
value = {
"<T:",
"Ljava/lang/Object;",
"R:",
"Ljava/lang/Object;",
">(",
"Ljava/lang/Class;",
"Ljava/lang/reflect/Constructor;",
"Lcom/saurik/substrate/MS$MethodAlteration",
"<TT;TR;>;)V"
}
.end annotation
.prologue
.line 112
.local p2, alteration:Lcom/saurik/substrate/MS$MethodAlteration;,"Lcom/saurik/substrate/MS$MethodAlteration<TT;TR;>;"
invoke-static {p0, p1, p2}, Lcom/saurik/substrate/MS;->hookMethod_(Ljava/lang/Class;Ljava/lang/reflect/Member;Lcom/saurik/substrate/MS$MethodAlteration;)V
.line 113
return-void
.end method
对应代码为:
public static <T, R> void hookMethod(Class paramClass, Constructor paramConstructor, MethodAlteration<T, R> paramMethodAlteration)
{
hookMethod_(paramClass, paramConstructor, paramMethodAlteration);
}
8. finally语句块
finally 语句块作用:执行一些必要代码。即不管出现异常与否,在finally中的代码都会被执行
执行时机:针对所有catch语句之后,退出方法之前将被执行(即先执行catch里面的代码,但在throw之前将转向finally)。finally中返回的结果将可以覆盖catch中返回的结果
对应的smail代码如下: :try_start_0
new-instance v2, Ljava/net/ServerSocket;
const/16 v3, 0x2710
invoke-direct {v2, v3}, Ljava/net/ServerSocket;-><init>(I)V
.line 21
.local v2, serverSocket:Ljava/net/ServerSocket;
invoke-virtual {v2}, Ljava/net/ServerSocket;->accept()Ljava/net/Socket;
:try_end_0
.catchall {:try_start_0 .. :try_end_0} :catchall_0 //处理start_0对应的异常块是catchall_0 也就是finally
.catch Ljava/io/IOException; {:try_start_0 .. :try_end_0} :catch_0//处理start_0对应的异常块是catch_0,catch_0异常块先执行,之后再执行catchall_0
源代码为:
try {
ServerSocket serverSocket= new ServerSocket(10000);
Socket socket=serverSocket.accept();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
int abc=5;
Toast.makeText(this, "sssss ", Toast.LENGTH_SHORT).show();
}
想对应的代码为:
const/4 v5, 0x0
.line 17
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
.line 18
const/high16 v3, 0x7f03
invoke-virtual {p0, v3}, Lcom/example/finallytest/MainActivity;->setContentView(I)V
.line 20
:try_start_0
new-instance v2, Ljava/net/ServerSocket;
const/16 v3, 0x2710
invoke-direct {v2, v3}, Ljava/net/ServerSocket;-><init>(I)V
.line 21
.local v2, serverSocket:Ljava/net/ServerSocket;
invoke-virtual {v2}, Ljava/net/ServerSocket;->accept()Ljava/net/Socket;
:try_end_0
.catchall {:try_start_0 .. :try_end_0} :catchall_0
.catch Ljava/io/IOException; {:try_start_0 .. :try_end_0} :catch_0
.line 27
const/4 v0, 0x5
@正常流程 即未发生异常
.line 28
.local v0, abc:I
const-string v3, "sssss "
invoke-static {p0, v3, v5}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v3
invoke-virtual {v3}, Landroid/widget/Toast;->show()V
.line 32
.end local v2 #serverSocket:Ljava/net/ServerSocket;
:goto_0
return-void
.line 22
.end local v0 #abc:I
:catch_0
@当发生异常时执行
move-exception v1
.line 24
.local v1, e:Ljava/io/IOException;
:try_start_1
invoke-virtual {v1}, Ljava/io/IOException;->printStackTrace()V
:try_end_1
.catchall {:try_start_1 .. :try_end_1} :catchall_0
@异常部分执行完毕,转而执行finally
.line 27
const/4 v0, 0x5
.line 28
.restart local v0 #abc:I
const-string v3, "sssss "
invoke-static {p0, v3, v5}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v3
invoke-virtual {v3}, Landroid/widget/Toast;->show()V
goto :goto_0
.line 25
.end local v0 #abc:I
.end local v1 #e:Ljava/io/IOException;
@finally代码定义部分
:catchall_0
move-exception v3
.line 27
const/4 v0, 0x5
.line 28
.restart local v0 #abc:I
const-string v4, "sssss "
invoke-static {p0, v4, v5}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v4
invoke-virtual {v4}, Landroid/widget/Toast;->show()V
.line 30
throw v3
|