AndroidStudio封裝jar並混淆

    公司和A公司有技術合做,須要把接口封裝成sdk供A公司調用,我被安排來作這個事情。這裏記錄一下封裝jar並混淆的過程當中遇到的一些問題,本文使用的IDE是AndroidStudio。java

    1.新建項目以後看到proguard-rules.pro中並無混淆java文件的代碼,因而百度-->>複製-->>粘貼-->>運行,但是反編譯apk以後發現根本沒有混淆代碼。這是真麼回事呢?proguard-rules.pro文件寫錯了?沒有配置到gradle文件裏?查了不少資料,再加上屢次的實驗,我終於找到問題的所在。以前一直看到gradle文件配置混淆文件的上面還有一行——minifyEnabled false 歷來沒有深究過有什麼意義(之後仍是要多研究一下這些不起眼的小細節,沒準那一天就把你拌趴下了),原來這個標誌就是代碼混淆的開關,默認是關閉的,因此以前雖然配置了混淆文件,可是並無執行代碼混淆。把這個標誌位置爲true,再運行就發現混淆起做用了。結論:進行代碼混淆時,要先把開關(minifyEnabled )打開!android

    2.如何封裝jar包呢?只在AndroidStudio上建立過工程,怎麼才能達成jar包呢?網上介紹了一些方法,讓我在gradle文件裏面新建任務大概是這個樣子json

task makeJar(type: Copy) {
    delete 'build/libs/mysdk.jar'
    from('build/intermediates/bundles/release/')
    into('build/libs/')
    include('classes.jar')
    rename ('classes.jar', 'mysdk.jar')
}

makeJar.dependsOn(build)

    一開始我也是這麼作的,還真的在build/libs目錄下面生成了一個mysdk.jar文件。後來仔細看了這一段代碼,發現這段代碼先是執行了build,而後把build/intermediates/bundles/release目錄下成的classes.jar文件改了一個名字而已,實在是太雞肋了。你本身運行工程,直接把build/intermediates/bundles/release目錄下的classes.jar拷貝出來就好了,不必這麼麻煩。結論:build輸出文件中已包含jar包,沒必要再想辦法生成jar,jar包位置build/intermediates/bundles/release/classes.jarbash

    3.封裝什麼東西?因爲合做的事情還在談,我並不知道最終的交付的sdk有什麼要求,因此我作了兩個方面的嘗試,第一:僅封裝接口;第二:提供接口和UI。先說第一種,我使用的方法和通常添加Module Library並不相同,我只是添加了一個普通的java的jar,Module中只有代碼和gralde沒有Manifest,沒有res。下面是個人gradle文件,幫助理解網絡

apply plugin: 'java'
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile files('libs/android.jar')
    compile 'com.google.code.gson:gson:2.5'
    compile 'com.squareup.okhttp:okhttp:2.5.0'
    compile 'com.squareup.okio:okio:1.6.0'
}

 

    這個地方有幾點須要注意的,android.jar去哪裏找?我注意到工程的最下面有一個External Library目錄,這個目錄關聯了工程的依賴文件。右鍵以後選擇file path就能夠看到jar的位置了,而後去這個目錄下邊拷貝出來就好了。像這樣app

我嘗試講gson、okhttp的jar包也經過compile files引用,可是在主工程裏面提示類沒有定義,只有經過這種方式,纔不會報錯。結論:我封裝的jar和界面沒有關係,因此我用了一種更乾淨的方法,來生成jar。ide

    4.運行程序,由於我沒有使用「apply plugin: 'com.android.library'」因此目錄結構跟上面又不太同樣,個人目錄結構是這樣的,module名爲meddo工具

能夠看到build/libs下面已經生成好了一個jar。我把meddo.jar文件拷貝出來開始進行混淆。gradle

    5.jar混淆,這裏使用的是sdk中包含的工具,具體位置sdk\tools\proguard\bin\proguardgui.bat。使用這個工具以前要作好準備工做:a.準備好要混淆的jar(上面的meddo.jar);b.準備好jar中使用的第三方jar(我這裏使用到了android.jar,okhttp-2.5.0.jar,okio-1.6.0.jar,gson-2.5.jar);c.準備好混淆配置文件ui

    介紹一下我這邊項目的具體狀況:I)我寫了一個外觀類MeddoInterface,並在這個類中開放出兩個方法init(Context)和UserLogin(HashMap<String,String>,ResultCallBack<UserLoginResponse>)  II)封裝了訪問網絡的操做,使用的是okhttp,中間用到了Gson,反射來解析數據

下面是混淆文件,有些冗餘的東西,不要見怪

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-dontshrink#混淆jar的時候必定要配置,否則會把沒有用到的代碼所有remove   我原本封裝一個jar就是給別人調用的,所有刪掉就沒有東西了
-verbose

-keepattributes Signature #過濾泛型 用到發射,泛型等要添加這個
-keepattributes *Annotation* 

-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

#若是你使用了ProGuard來導入第三方jar這個地方就不用配置了
#-libraryjars ../meddo/libs/android.jar
#-libraryjars ../meddo/libs/gson-2.5.jar
#-libraryjars ../meddo/libs/okhttp-2.5.0.jar
#-libraryjars ../meddo/libs/okio-1.6.0.jar

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class com.android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembernames class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
#公開兩個方法供使用者調用
-keep public class com.hsji.makejar.MeddoInterface{
 public static void UserLogin(java.util.HashMap, com.hsji.makejar.network.ResultCallback);
 public static void init(android.content.Context);
}
#解析數據是用的的bean  徹底不混淆,否則解析json數據時什麼都找不到
-keep public class com.hsji.makejar.UserLoginResponse{*;}
#不要混淆ResultCallback的public方法
-keep public class com.hsji.makejar.network.ResultCallback{
 public <methods>;
}

#okhttp
-dontwarn com.squareup.okhttp.**

-keep class com.squareup.okhttp.** { *;}

-dontwarn okio.**

-keep class okio.** {*;}

#json
-dontwarn com.google.gson.**

-keep class com.google.gson.**{*;}

 ok,如今咱們原料都有了,開始混淆吧!

 step1:

 導入ProGuard配置文件

step2:導入須要混淆的jar和第三方jar,填寫輸出文件,這裏額外添加一個一個java\jre7\lib\rt.jar(具體以本身電腦環境爲準)

step3:進入Process標籤頁,點擊右下角的Process!按鈕,開始混淆,很快就混淆好了

 

注:以上爲我的的方法,不喜勿噴

      關於proguard文件的配置能夠參考這篇文章《android 混淆文件proguard.cfg詳解》

相關文章
相關標籤/搜索