Android開發(fā)實(shí)踐:利用ProGuard進(jìn)行代碼混淆

由于Android的代碼大都是Java代碼,所以挺容易被反編譯的,好在Android ADT為我們集成了混淆代碼的工具,一來可以混淆我們的代碼,讓程序被反編譯后基本看不懂,另外還能起到代碼優(yōu)化的作用。發(fā)布項(xiàng)目前,建議打開Android的代碼混淆功能。

創(chuàng)新互聯(lián)專注于宜春企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè),購(gòu)物商城網(wǎng)站建設(shè)。宜春網(wǎng)站建設(shè)公司,為宜春等地區(qū)提供建站服務(wù)。全流程專業(yè)公司,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)


Android ADT主要通過ProGuard工具來提供代碼混淆,網(wǎng)上也有挺多博客文章講這個(gè)的,但感覺很多都介紹得太過于復(fù)雜,這里我就以問答的方式來更加簡(jiǎn)潔地介紹下ProGuard吧。


1. ProGuard是什么


ProGuard是一個(gè)工具,用來混淆和優(yōu)化Java代碼。


工作方式:移除無效的代碼,將代碼中的類名、函數(shù)名替換為晦澀難懂的名字。


注意,它只能混淆Java代碼,Android工程中Native代碼,資源文件(圖片、xml),它是無法混淆的。


2. 如何開啟ProGuard


修改Android工程根目錄下的project.properties文件,把proguard.config=....這一行前面的注釋“#”去掉。


這一行指定了系統(tǒng)默認(rèn)的proguard配置文件,位于Android SDK/tools/proguard目錄下。


當(dāng)然,你也可以自己編寫配置文件,但不建議這樣做,因此系統(tǒng)默認(rèn)的配置已經(jīng)涵蓋了許多通用的細(xì)節(jié),如果你還有額外的配置,可以添加在 proguard-project.txt 文件中。


注意: 只有在生成release版本的apk時(shí),混淆配置才會(huì)起作用,debug版本的apk不會(huì)進(jìn)行混淆。


3. 哪些內(nèi)容需要手動(dòng)配置


系統(tǒng)默認(rèn)的配置已經(jīng)涵蓋了大部分的內(nèi)容,但是如果你的工程中有如下內(nèi)容,則需要手動(dòng)添加配置到proguard-project.txt文件中。


(1) 只在 AndroidManifest.xml 引用的類

(2) 通過JNI回調(diào)方式被調(diào)用的函數(shù)

(3) 運(yùn)行時(shí)動(dòng)態(tài)調(diào)用的函數(shù)或者成員變量

(4) 當(dāng)然,如果你不確定哪些需要手動(dòng)配置,可以以默認(rèn)的配置生成程序,當(dāng)運(yùn)行中發(fā)現(xiàn)ClassNotFoundException異常時(shí),即可找到哪個(gè)類不該被混淆。


4. 手動(dòng)配置的規(guī)則


手動(dòng)添加的配置,一般以“-keep”開頭,常用的配置命令分別示例如下:


假設(shè)Android工程中有一個(gè)接口和一個(gè)類:

package com.ticktick.example;
                                                                                                                                                                                                                                                                                                                                                       
public interface TestInterface {
    public void test();
}
                                                                                                                                                                                                                                                                                                                                        
public class Test {
                                                                                                                                                                                                                                                                                                                                            
    private String mTestString;
    private final int mMinValue;
    private final int mMaxValue;
                                                                                                                                                                                                                                                                                                                                              
    public Test( int min, int max){
        mMinValue = min;
        mMaxValue = max;
    }
                                                                                                                                                                                                                                                                                                                                                        
    public int getMinValue() {
        return mMinValue;
    }
                                                                                                                                                                                                                                                                                                                                                   
    public int getMaxValue() {
        return mMaxValue;
    }
                                                                                                                                                                                                                                                                                                                                                   
    public void setTestString(String testStr ) {
        mTestString = testStr;
    }
}

(1) 不混淆某個(gè)類的構(gòu)造函數(shù)


例如:不混淆Test類的構(gòu)造函數(shù):

-keepclassmembers class
com.ticktick.example.Test {
    public <init>(int,int);
}


(2) 不混淆某個(gè)包所有的類或指定的類

例如,不混淆package com.ticktick.example下的所有類/接口

-keep class com.ticktick.example.** { * ; }

例如,不混淆com.ticktick.example.Test類:

-keep class com.ticktick.example.Test { * ; }

如果希望不混淆某個(gè)接口,則把上述命令中的class替換為interface即可。


(3) 不混淆某個(gè)類的特定的函數(shù)


例如:不混淆com.ticktick.example.Test類的setTestString函數(shù):

-keepclassmembers class
com.ticktick.example.Test {
    public void setTestString(java.lang.String);
}


(4) 不混淆某個(gè)類的子類,某個(gè)接口的實(shí)現(xiàn)


例如:不混淆com.ticktick.example.Test類的子類

-keep public class * extends com.ticktick.example.Test

例如:不混淆com.ticktick.example.TestInterface的實(shí)現(xiàn)

-keep class * implementscom.ticktick.example.TestInterface {
    public static final com.ticktick.example.TestInterface$Creator *;
}


(5) 添加第三方依賴包


例如:添加android-support-v4.jar依賴包

-libraryjars
libs/android-support-v4.jar
-dontwarn
android.support.v4.**{*;}
-keep class android.support.v4.**{*;}
-keep interface android.support.v4.**{*;}


注意: 需要添加dontwarn,因?yàn)槟J(rèn)情況下proguard會(huì)檢查每一個(gè)引用是否正確,但是第三方庫(kù)里往往有些不會(huì)用到的類,沒有正確引用,所以如果不配置的話,系統(tǒng)會(huì)報(bào)錯(cuò)。


5. 混淆后的調(diào)試信息解析


當(dāng)代碼混淆之后,輸出的Log信息也會(huì)帶有混淆內(nèi)容,比如函數(shù)名和類名會(huì)被替換為晦澀難懂的名字,而與代碼中的不一致。


因此,ProGuard工具還提供了恢復(fù)混淆內(nèi)容的工具和文件。


當(dāng)你開啟了ProGuard混淆后,每次生成release版的apk時(shí),Andriod工程的根目錄下會(huì)對(duì)應(yīng)生成一個(gè)proguard文件夾,該文件夾下的mapping.txt文件記錄了混淆后的名字與混淆前的名字的對(duì)應(yīng)關(guān)系,通過該文件,我們反向得到恢復(fù)后的Log信息。


假設(shè)Log文件名為log.txt,則恢復(fù)混淆的命令為:

$retrace.sh -verbose mapping.txt log.txt

注1:retrace.sh命令位于 <sdk_root>/tools/proguard/目錄下

注2:你需要保存每一個(gè)release版本的mapping.txt,因?yàn)槊恳淮蝦elease的混淆結(jié)果和映射關(guān)系都不一樣。


關(guān)于Android的代碼混淆我就總結(jié)到這兒了,你也可以去ProGuard的官方網(wǎng)頁上獲取關(guān)于ProGuard更加詳細(xì)的介紹,有任何疑問歡迎留言或者來信lujun.hust@gmail.com交流,或者關(guān)注我的新浪微博 @盧_俊 獲取最新的文章和資訊。

   

網(wǎng)頁標(biāo)題:Android開發(fā)實(shí)踐:利用ProGuard進(jìn)行代碼混淆
網(wǎng)站路徑:http://bm7419.com/article4/psscie.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站營(yíng)銷型網(wǎng)站建設(shè)、靜態(tài)網(wǎng)站、品牌網(wǎng)站建設(shè)、微信公眾號(hào)、ChatGPT

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作