馬上加入Android 台灣中文網,立即免費下載應用遊戲。
您需要 登錄 才可以下載或查看,沒有帳號?註冊  
 
x
 
一 、smali資料類型 1.Dalvik位元組碼 
 Davlik位元組碼中,寄存器都是32位的,能夠支援任何類型,64位類型(Long/Double)用2個連續的寄存器表示; 
 Dalvik位元組碼有兩種類型:原始類型;引用類型(包括對像和數組) 
  
原始類型:          v   void  只能用於返回值類型           Z   boolean           B   byte           S   short           C   char           I    int           J    long(64位)           F   float           D   double(64位) 對像類型: Lpackage/name/ObjectName;       相當於java中的package.name.ObjectName;      L:表示這是一個對像類型      package/name:該對像所在的包     ;:表示對像名稱的結束 
2.數組的表示形式: [I  :表示一個整形的一維數組,相當於java的int[];對於多維數組,只要增加[ 就行了,[[I = int[][];註:每一維最多255個; 對像數組的表示形式:[Ljava/lang/String表示一個String的對象數組; 
3.方法的表示形式:   Lpackage/name/ObjectName;->methodName(III)Z           Lpackage/name/ObjectName  表示類型           methodName   表示方法名           III   表示參數(這裡表示為3個整型參數)說明:方法的參數是一個接一個的,中間沒有隔開 
4.字段的表示形式: Lpackage/name/ObjectName;->FieldName:Ljava/lang/String;即表示:包名,字段名和字段類型 
5.寄存器指定 有兩種方式指定一個方法中有多少寄存器是可用的: .registers  指令指定了方法中寄存器的總數 .locals    指令表明了方法中非參寄存器的總數,出現在方法中的第一行 
6.方法的表示 方法有直接方法和虛方法兩種,直接方法的聲明格式如下: .method<存取權限>[修飾關鍵字]<方法原型> <.locals> [.parameter] [.prologue] [.line] <代碼體> .end method 
存取權限有public、private等,修飾關鍵字有static、constructor等。方法原型描述了方法的名稱、參數與返回值。 .registers指定了方法中寄存器的總數 .locals指定了方法中非參寄存器的總數(局部變量的個數); .parameter指定了方法的參數; .prologue指定了代碼的開始處; .line指定了該處指令在源代碼中的位置。 
注意:構造函數的返回類型為V,名字為<init>。 
7.方法的傳參: 當一個方法被調用的時候,方法的參數被置於最後N個寄存器中; 例如:一個方法有2個參數,5個寄存器(v0~v4),那麼,參數將置於最後2個寄存器(v3和v4)。非靜態方法中的第一個參數總是調用該方法的對象。 說明:對於靜態方法除了沒有隱含的this參數外,其他都一樣 
8.寄存器的命名方式:V命名、P命名 第一個寄存器就是方法中的第一個參數寄存器。比較:使用P命名是為了防止以後如果在方法中增加寄存器,需要對參數寄存器重新進行編號的缺點。特別說明一下:Long和Double類型是64位的,需要2個連續的寄存器 例如:對於非靜態方法LMyObject->myMethod(IJZ)V,有4個參數:  LMyObject(隱含的),int,long,boolean 需要5個寄存器(因為long佔有2個連續的寄存器)來存儲參數:      P0    this(非靜態方法中這個參數是隱含的)      P1    I (int)      P2,P3  J (long)      P4    Z(bool) 如果是靜態的就是三個參數      P0   I (int)      P1,P2 J (long)      P3    Z(bool) 
 
二、成員變量 
# static fields             定義靜態變量的標記 
# instance fields        定義實例變量的標記 
# direct methods       定義靜態方法的標記 
# virtual methods      定義非靜態方法的標記 
 
三、控制條件  "if-eq vA, vB, :cond_**"   如果vA等於vB則跳轉到:cond_** 
"if-ne vA, vB, :cond_**"   如果vA不等於vB則跳轉到:cond_** 
"if-lt vA, vB, :cond_**"    如果vA小於vB則跳轉到:cond_** 
"if-ge vA, vB, :cond_**"   如果vA大於等於vB則跳轉到:cond_** 
"if-gt vA, vB, :cond_**"   如果vA大於vB則跳轉到:cond_** 
"if-le vA, vB, :cond_**"    如果vA小於等於vB則跳轉到:cond_** 
"if-eqz vA, :cond_**"   如果vA等於0則跳轉到:cond_** 
"if-nez vA, :cond_**"   如果vA不等於0則跳轉到:cond_** 
"if-ltz vA, :cond_**"    如果vA小於0則跳轉到:cond_** 
"if-gez vA, :cond_**"   如果vA大於等於0則跳轉到:cond_** 
"if-gtz vA, :cond_**"   如果vA大於0則跳轉到:cond_** 
"if-lez vA, :cond_**"    如果vA小於等於0則跳轉到:cond_** 
 
z 既可以表示zero(0) 也可以是null、或者false;具體看邏輯。 
  
四、switch分支語句  
- .method private packedSwitch(I)Ljava/lang/String;  
 
 -     .locals 1  
 
 -     .parameter "i"  
 
 -     .prologue  
 
 -     .line 21  
 
 -     const/4 v0, 0x0  
 
 -     .line 22  
 
 -     .local v0, str:Ljava/lang/String;  #v0為字符串,0表示null  
 
 -     packed-switch p1, :pswitch_data_0  #packed-switch分支,pswitch_data_0指定case區域  
 
 -     .line 36  
 
 -     const-string v0, "she is a person"  #default分支  
 
 -     .line 39  
 
 -     :goto_0      #所有case的出口  
 
 -     return-object v0 #返回字符串v0  
 
 -     .line 24  
 
 -     :pswitch_0    #case 0  
 
 -     const-string v0, "she is a baby"  
 
 -     .line 25  
 
 -     goto :goto_0  #跳轉到goto_0標號處  
 
 -     .line 27  
 
 -     :pswitch_1    #case 1  
 
 -     const-string v0, "she is a girl"  
 
 -     .line 28  
 
 -     goto :goto_0  #跳轉到goto_0標號處  
 
 -     .line 30  
 
 -     :pswitch_2    #case 2  
 
 -     const-string v0, "she is a woman"  
 
 -     .line 31  
 
 -     goto :goto_0  #跳轉到goto_0標號處  
 
 -     .line 33  
 
 -     :pswitch_3    #case 3  
 
 -     const-string v0, "she is an obasan"  
 
 -     .line 34  
 
 -     goto :goto_0  #跳轉到goto_0標號處  
 
 -     .line 22  
 
 -     nop  
 
 -     :pswitch_data_0  
 
 -     .packed-switch 0x0    #case  區域,從0開始,依次遞增  
 
 -         :pswitch_0  #case 0  
 
 -         :pswitch_1  #case 1  
 
 -         :pswitch_2  #case 2  
 
 -         :pswitch_3  #case 3  
 
 -     .end packed-switch  
 
 - .end method
 
  複製代碼 
packed-switch 指令。p1為傳遞進來的 int 類型的數值,pswitch_data_0 為case 區域,在 case 區域中,第一條指令「.packed-switch」指定了比較的初始值為0 ,pswitch_0~ pswitch_3分別是比較結果為「case 0 」到「case 3 」時要跳轉到的地址。可以發現,標號的命名採用 pswitch_ 開關,後面的數值為 case 分支需要判斷的值,並且它的值依次遞增。再來看看這些標號處的代碼,每個標號處都使用v0 寄存器初始化一個字符串,然後跳轉到了goto_0 標號處,可見goto_0 是所有的 case 分支的出口。另外,「.packed-switch」區域指定的case 分支共有4 條,對於沒有被判斷的 default 分支,會在代碼的 packed-switch指令下面給出。 
至此,有規律遞增的 switch 分支就算是搞明白了。最後,將這段 smali 代碼整理為Java代碼如下。 
- private String packedSwitch(int i) {  
 
 -     String str = null;  
 
 -     switch (i) {  
 
 -         case 0:  
 
 -             str = "she is a baby";  
 
 -             break;  
 
 -         case 1:  
 
 -             str = "she is a girl";  
 
 -             break;  
 
 -         case 2:  
 
 -             str = "she is a woman";  
 
 -             break;  
 
 -         case 3:  
 
 -             str = "she is an obasan";  
 
 -             break;  
 
 -         default:  
 
 -             str = "she is a person";  
 
 -             break;  
 
 -     }  
 
 -     return str;  
 
 - }
 
  複製代碼 
現在我們來看看無規律的case 分支語句代碼會有什麼不同 
- .method private sparseSwitch(I)Ljava/lang/String;  
 
 -     .locals 1  
 
 -     .parameter "age"  
 
 -     .prologue  
 
 -     .line 43  
 
 -     const/4 v0, 0x0  
 
 -     .line 44  
 
 -     .local v0, str:Ljava/lang/String;  
 
 -     sparse-switch p1, :sswitch_data_0  # sparse-switch分支,sswitch_data_0指定case區域  
 
 -     .line 58  
 
 -     const-string v0, "he is a person"  #case default  
 
 -     .line 61  
 
 -     :goto_0    #case 出口  
 
 -     return-object v0  #返回字符串  
 
 -     .line 46  
 
 -     :sswitch_0    #case 5  
 
 -     const-string v0, "he is a baby"  
 
 -     .line 47  
 
 -     goto :goto_0 #跳轉到goto_0標號處  
 
 -     .line 49  
 
 -     :sswitch_1    #case 15  
 
 -     const-string v0, "he is a student"  
 
 -     .line 50  
 
 -     goto :goto_0 #跳轉到goto_0標號處  
 
 -     .line 52  
 
 -     :sswitch_2    #case 35  
 
 -     const-string v0, "he is a father"  
 
 -     .line 53  
 
 -     goto :goto_0 #跳轉到goto_0標號處  
 
 -     .line 55  
 
 -     :sswitch_3    #case 65  
 
 -     const-string v0, "he is a grandpa"  
 
 -     .line 56  
 
 -     goto :goto_0 #跳轉到goto_0標號處  
 
 -     .line 44  
 
 -     nop  
 
 -     :sswitch_data_0  
 
 -     .sparse-switch            #case 區域  
 
 -         0x5 -> :sswitch_0     #case 5(0x5)  
 
 -         0xf -> :sswitch_1     #case 15(0xf)  
 
 -         0x23 -> :sswitch_2    #case 35(0x23)  
 
 -         0x41 -> :sswitch_3    #case 65(0x41)  
 
 -     .end sparse-switch  
 
 - .end method
 
  複製代碼 
按照分析packed-switch 的方法,我們直接查看 sswitch_data_0 標號處的內容。可以看到「.sparse-switch 」指令沒有給出初始case 的值,所有的case 值都使用「case 值 -> case 標號」的形式給出。此處共有4 個case ,它們的內容都是構造一個字符串,然後跳轉到goto_0 標號處,代碼架構上與packed-switch 方式的 switch 分支一樣。 
最後,將這段smali 代碼整理為Java 代碼如下。 
- private String sparseSwitch(int age) {  
 
 -     String str = null;  
 
 -     switch (age) {  
 
 -         case 5:  
 
 -             str = "he is a baby";  
 
 -             break;  
 
 -         case 15:  
 
 -             str = "he is a student";  
 
 -             break;  
 
 -         case 35:  
 
 -             str = "he is a father";  
 
 -             break;  
 
 -         case 65:  
 
 -             str = "he is a grandpa";  
 
 -             break;  
 
 -         default:  
 
 -             str = "he is a person";  
 
 -             break;  
 
 -     }  
 
 -     return str;  
 
 - }
 
  複製代碼 五、try/catch 语句  
- .method private tryCatch(ILjava/lang/String;)V  
 
 -     .locals 10  
 
 -     .parameter "drumsticks"  
 
 -     .parameter "peple"  
 
 -     .prologue  
 
 -     const/4 v9, 0x0  
 
 -                                                                                                                                                               .line 19  
 
 -     try_start_0                                                                      # 第1個try開始  
 
 -     invoke-static {p2}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I           #將第2個參數轉換為int 型  
 
 -     :try_end_0                                                                       # 第1個try結束  
 
 -     .catch Ljava/lang/NumberFormatException; {:try_start_0 .. :try_end_0} : catch_1  # catch_1  
 
 -      move-result v1                                      #如果出現異常這裡不會執行,會跳轉到catch_1標號處  
 
 -                                                                                                                                                                .line 21  
 
 -     .local v1, i:I                                      #.local聲明的變量作用域在.local聲明與.end local 之間  
 
 -    :try_start_1                                     #第2個try 開始  
 
 -     div-int v2, p1, v1                                      # 第1個參數除以第2個參數  
 
 -     .line 22  
 
 -     .local v2, m:I      
 
 -     mul-int v5, v2, v1                                                   #m * i  
 
 -     sub-int v3, p1, v5                                                              #v3  = p1 - v5  
 
 -     .line 23  
 
 -     .local v3, n:I  
 
 -     const-string v5, "u5171u6709%du53eau9e21u817fuff0c%d  
 
 -         u4e2au4ebau5e73u5206uff0cu6bcfu4ebau53efu5206u5f97%d  
 
 -         u53eauff0cu8fd8u5269u4e0b%du53ea"   # 格式化字符串  
 
 -     const/4 v6, 0x4  
 
 -     new-array v6, v6, [Ljava/lang/Object;  
 
 -     const/4 v7, 0x0  
 
 -     .line 24  
 
 -     invoke-static {p1}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;  
 
 -     move-result-object v8  
 
 -     aput-object v8, v6, v7  
 
 -     const/4 v7, 0x1  
 
 -     invoke-static {v1}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;  
 
 -     move-result-object v8  
 
 -     aput-object v8, v6, v7  
 
 -     const/4 v7, 0x2  
 
 -     invoke-static {v2}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;  
 
 -     move-result-object v8  
 
 -     aput-object v8, v6, v7  
 
 -     const/4 v7, 0x3  
 
 -     invoke-static {v3}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;  
 
 -     move-result-object v8  
 
 -    
 
 -     aput-object v8, v6, v7  
 
 -     .line 23  
 
 -     invoke-static {v5, v6}, Ljava/lang/String;  
 
 -         ->format(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;  
 
 -     move-result-object v4  
 
 -     .line 25  
 
 -     .local v4, str:Ljava/lang/String;  
 
 -     const/4 v5, 0x0  
 
 -     invoke-static {p0, v4, v5}, Landroid/widget/Toast;  
 
 -         ->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)  
 
 -         Landroid/widget/Toast;  
 
 -     move-result-object v5  
 
 -     invoke-virtual {v5}, Landroid/widget/Toast;->show()V                 # 使用Toast 顯示格式化後的結果  
 
 -    :try_end_1                                           #第2個try 結束  
 
 -     .catch Ljava/lang/ArithmeticException; {:try_start_1 .. :try_end_1} : catch_0       # catch_0  
 
 -     .catch Ljava/lang/NumberFormatException; {:try_start_1 .. :try_end_1} : catch_1     # catch_1  
 
 -     .line 33  
 
 -     .end local v1           #i:I  
 
 -     .end local v2           #m:I  
 
 -     .end local v3           #n:I  
 
 -     .end local v4           #str:Ljava/lang/String;  
 
 -     :goto_0   
 
 -     return-void                                                                     # 方法返回  
 
 -     .line 26   
 
 -     .restart local v1       #i:I  
 
 -     :catch_0     
 
 -     move-exception v0  
 
 -     .line 27  
 
 -     .local v0, e:Ljava/lang/ArithmeticException;  
 
 -                                                                                                                                                               :try_start_2                                     #第3個try 開始  
 
 -     const-string v5, "u4ebau6570u4e0du80fdu4e3a0"                                  #「人數不能為0」  
 
 -     const/4 v6, 0x0  
 
 -     invoke-static {p0, v5, v6}, Landroid/widget/Toast;  
 
 -         ->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)  
 
 -         Landroid/widget/Toast;  
 
 -     move-result-object v5  
 
 -     invoke-virtual {v5}, Landroid/widget/Toast;->show()V         #使用Toast 顯示異常原因  
 
 -     :try_end_2                                                   #第3個try 結束  
 
 -     .catch Ljava/lang/NumberFormatException; {:try_start_2 .. :try_end_2} :catch_1  
 
 -      goto :goto_0 #返回  
 
 -     .line 29  
 
 -     .end local v0           #e:Ljava/lang/ArithmeticException;  
 
 -     .end local v1           #i:I  
 
 -     :catch_1   
 
 -     move-exception v0  
 
 -     .line 30  
 
 -     .local v0, e:Ljava/lang/NumberFormatException;  
 
 -     const-string v5, "u65e0u6548u7684u6570u503cu5b57u7b26u4e32"   
 
 -     #「無效的數值字符串」  
 
 -     invoke-static {p0, v5, v9}, Landroid/widget/Toast;  
 
 -         ->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)  
 
 -         Landroid/widget/Toast;  
 
 -     move-result-object v5  
 
 -     invoke-virtual {v5}, Landroid/widget/Toast;->show()V  # 使用Toast 顯示異 常原因  
 
 -     goto :goto_0                                         #返回  
 
 - .end method
 
  複製代碼 
代碼中的try語句塊使用try_start_開頭的標號註明,以try_end_開頭的標號結束。第一個try語句的開頭標號為try_start_0,結束標號為 try_end_0。使用多個try語句塊時標號名稱後面的數值依次遞增,本實例代碼中最多使用到了try_end_2。 
在try_end_0 標號下面使用「.catch」指令指定處理到的異常類型與catch的標號,格式如下。 
 
.catch < 異常類型> {<try起始標號> .. <try 結束標號>} <catch標號> 
 
查看catch_1標號處的代碼發現,當轉換 String 到int 時發生異常會彈出「無效的數值字符串」的提示。對於代碼中的漢字,baksmali 在反編譯時將其使用Unicode進行編碼,因此,在閱讀前需要使用相關的編碼轉換工具進行轉換。 
 
仔細閱讀代碼會發現在try_end_1標號下面使用「.catch」指令定義了 catch_0與catch_1兩個catch。catch_0標號的代碼開頭又有一個標號為try_start_2的try 語句塊,其實這個try語句塊是虛構的,假如下面的代碼。 
- private void a() {  
 
 -     try {  
 
 -         ……  
 
 -         try {  
 
 -             ……  
 
 -         } catch (XXX) {  
 
 -             ……  
 
 -         }  
 
 -     } catch (YYY) {  
 
 -         ……  
 
 -     }        
 
 - }
 
  複製代碼 
當執行內部的try語句時發生了異常,如果異常類型為XXX,則內部catch就會捕捉到並執行相應的處理代碼,如果異常類型不是 XXX,那麼就會到外層的 catch中去查找異常處理代碼,這也就是為什麼實例的try_end_1標號下面會有兩個catch的原因,另外,如果在執行XXX異常的處理代碼時又發生了異常,這個時候該怎麼辦?此時這個異常就會擴散到外層的catch中去,由於XXX異常的外層只有一個YYY的異常處理,這時會判斷發生的異常是否為YYY類型,如果是就會進行處理,不是則拋給應用程式。回到本實例中來,如果在執行內部的ArithmeticException異常處理時再次發生別的異常,就會調用外層的 catch進行異常捕捉,因此在try_end_2標號下面有一個 catch_1就很好理解了。 
最後,將這段 smali 代碼整理為Java 代碼如下。 
- private void tryCatch(int drumsticks, String peple) {  
 
 -         try {  
 
 -             int i = Integer.parseInt(peple);  
 
 -             try {  
 
 -                 int m = drumsticks / i;  
 
 -                 int n = drumsticks - m * i;  
 
 -                 String str = String.format("共有%d隻雞腿,%d個人平分,每人可分得%d只,還剩下%d只",drumsticks, i, m, n);  
 
 -                 Toast.makeText(MainActivity.this, str,Toast.LENGTH_SHORT).show();  
 
 -             } catch (ArithmeticException e) {  
 
 -                 Toast.makeText(MainActivity.this, " 人數不能為0",Toast.LENGTH_SHORT).show();  
 
 -             }  
 
 -         } catch (NumberFormatException e) {  
 
 -             Toast.makeText(MainActivity.this, " 無效的數值字符串",Toast.LENGTH_SHORT).show();  
 
 -         }          
 
 - } 
 
  複製代碼 
finally語句塊 
- try {  
 
 -          ServerSocket serverSocket= new ServerSocket(10000);  
 
 -          Socket socket=serverSocket.accept();  
 
 -      } catch (IOException e) {  
 
 -          e.printStackTrace();  
 
 -      }finally{  
 
 -         int abc=5;  
 
 -         Toast.makeText(this, "sssss ", Toast.LENGTH_SHORT).show();  
 
 -  }
 
  複製代碼 
finally 語句塊作用:執行一些必要代碼。即不管出現異常與否,在finally中的代碼都會被執行 
執行時機:針對所有catch語句之後,退出方法之前將被執行(即先執行catch裡面的代碼,但在throw之前將轉向finally)。finally中返回的結果將可以覆蓋catch中返回的結果 
對應的smail代碼如下:  
:try_start_0 
    new-instance v2, Ljava/net/ServerSocket;                                   #ServerSocket v2 = null;    
    const/16 v3, 0x2710                                                                   # v3 = 10000; 
    invoke-direct {v2, v3}, Ljava/net/ServerSocket;-><init>(I)V       # v2 = new ServerSocket(v3); 
    .line 21 
    .local v2, serverSocket:Ljava/net/ServerSocket; 
    invoke-virtual {v2}, Ljava/net/ServerSocket;->accept()Ljava/net/Socket;   # v2.accept( ); 
    :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   
 
 
想對應的smali代碼為:  
   
    :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 |