一、混淆的概念
將Android項目進行打包之時,可以將項目里的包名、類名、變量名進行更改,使得代碼不容易泄露,類似于對其apk中的文件加密。
二、混淆的作用
? ? ? ?首先,大家要知道,Android項目直接打成apk包之后,其實是可以通過一定的反編譯技術手段看到apk中的源碼,這對于一些商業項目(非開源項目)來說,肯定是不合適的,而“混淆”可以一定程度的避免apk被簡單的反編譯,從而被其他人窺視到apk包中的奧秘。
? ? ? ?所以,簡而言之,混淆的作用:
? ? ? ? ? ?1.?代碼混淆后閱讀性降低,反編譯后破譯程序難度提高;
? ? ? ? ? ?2. 混淆后字節數減少,減少了應用了體積
三、什么是混淆,什么是避混
? ? ? ?Android SDK 本身就提供混淆的功能,將混淆開關進行開啟后(下文會舉例說明如何開啟),開發者需要做的是對Android Studio工程項目中的proguard-rules.pro文件進行混淆白名單的配置,也就是所謂的將某個或某些指定文件進行避混處理。
? ? ? ?那么什么是混淆白名單呢?其實就是指定一些包名、類名、變量等不可以被混淆。假設沒指定白名單就進行混淆打包,而某某類的類名被混淆了(假設變成了a),那么可能其他引用或使用該類的類就找不到該類,說不定應用就會因此崩潰或是導致相應的功能無法使用。
比如端內直連Jira的SDK提供給外部調用的類A和方法fun,是在DevConfig文件中通過反射的方式調用的,如果SDK提供的這些類和方法被混淆了,那么類A和方法fun的名字就被改變了,導致反射的時候,找不到指定的類A和方法fun了。所以要對SDK中需要提供給外部操作的類A和方法fun進行避混處理。
? ? ? ?所以所謂的混淆也就是配置混淆白名單。
四、ProGuard文件
? ? ? 在Android中,混淆的內容被寫在了ProGuard文件中,例如:
? ? ? ProGuard里一共可以做三件事:
1.壓縮(Shrinking):默認開啟,用以減小應用體積,移除未被使用的類和成員,并且會在優化動作執行之后再次執行(因為優化后可能會再次暴露一些未被使用的類和成員)。
? ? ? ? ? ? ? ? ? ? 關閉壓縮的方法:-dontshrink
? ? ? ? ?公司App中,采用的是開啟壓縮。
2.優化(Optimization):默認開啟,在字節碼級別執行優化,讓應用運行的更快。
? ? ? ? ? ? ? ? ? ?關閉優化的方法:-dontoptimize 關閉優化
? ? ? ? 使用方法:-optimizationpasses n 表示proguard對代碼進行迭代優化的次數,Android一般為5
? ? ? ? ? ? ? ? ? ?公司App中,采用了優化,且該值為5。
3.混淆(Obfuscation):默認開啟,增大反編譯難度,類和類成員會被隨機命名,除非用keep保護。
? ? ? ? ? ? ? ? ? ? 關閉混淆的方法:-dontobfuscate 關閉混淆
? ? ? ? ?公司App中,開啟了混淆,混淆的具體內容,就在proguard-project.txt中。
? ? ? ?本文主要針對混淆進行簡單講解。
五、怎么實現混淆
? ? ? ? 以公司App舉例說明。
? ? ? ? 首先,在appmodule的build.gradle文件中,能看到:
? ? ? ? ?說明一下:
? ? ? ? ? ? ? ?1. 此處的release代表打release包時用的配置內容,debug為打debug包時用的配置內容,dev為打dev包時用到的配置內容。
2.minifyEnabled?false?代表不開啟混淆;minifyEnabled?true 代表開啟混淆
開啟混淆后,可以添加:shrinkResources?true?代表去掉沒有引用的資源,可以減少應用的體積,但這個只有在混淆開啟后才有效。
? ? ? ? ? ?從圖中可以明顯看到,debug雖然配置了混淆文件,但沒有開啟混淆;release、dev都開啟了混淆,且混淆文件都為同一份:proguard-project.txt,該文件在上面的(二)中,已經截圖給出來了。打開文件就能看到具體的內容。
? ? ? ? ? ?另外再做個說明,大家如果細心的話,應該會發現在上面(二)的截圖中,能看到不僅有proguard-project.txt,還有proguard-gen.txt、proguard-rn.txt,其實這2個文件都被包含在了proguard-project.txt中:
? ? ? ? 打開這兩個文件,會發現文件內容的格式與proguard-project.txt文件一致,不用懷疑,這兩個其實也是混淆文件。公司App根據各類和包的不同作用,將內容寫在了不同的proguard文件中。
? ? ? ? 項目編譯的時候,會先找到proguard-project.txt執行,之后執行的過程中,會將include進來的2個proguard文件一并做處理。
混淆后默認會在工程目錄app/build/outputs/mapping/release下生成一個mapping.txt文件,這就是混淆規則,我們可以根據這個文件把混淆后的代碼反推回源本的代碼,所以這個文件很重要,注意保護好。原則上,代碼混淆后越亂越無規律越好,但有些地方我們是要避免混淆的,否則程序運行就會出錯,所以就有了下面要說的:如何讓自己的部分代碼避免混淆從而防止出錯。
六、如何避混
? ? ? 需要避混的文件都需要一一添加到proguard文件中,先給出兩份比較全的混淆指令相關博客鏈接:
http://blog.csdn.net/yk377657321/article/details/60501880
http://blog.csdn.net/maxwell_nc/article/details/51998766
? ? ? 針對公司App中用到的語法,進行簡單說明:
1、# 代表行注釋符
2、-?表示一條規則的開始
3、keep 保留,例如keepattributes:表示保留屬性
4、dont 不要,例如dontwarn:表示不要提示警告
5、ignore 忽略,例如ignorewarning:表示忽略警告
6、-dontoptimize不優化 ,值得注意的是默認混淆配置文件開啟了-dontoptimize
7、-assumenosideeffects?關閉log
8、一般混淆規則都要加入,其中前兩個在默認文件中已經配置:
8.1、-dontusemixedcaseclassnames?包名不使用大小寫混合?aA Aa ? ?公司App中未開啟
8.2、-dontskipnonpubliclibraryclasses不混淆第三方引用的庫?公司App中未開啟
? ? ? ? ? ? ? ? ? ? ? ??8.3、-dontpreverify不做預校驗公司App中已開啟
? ? ? ? ? ? ? ? ? ? ? ? 8.4、?-ignorewarning忽略警告公司App中未開啟
? ? ? ? ? ? ?9、輸出混淆記錄:
9.1、-verbose混淆后生產映射文件 map 類名->轉化后類名的映射,存放在app\build\outputs\mapping\release中
9.2、-printmapping混淆前后的映射,公司App中是:out.map
10、保留原代碼行號:-keepattributes?拋出異常時保留代碼行號,這個最后release的時候關閉掉,公司App中是:Exceptions,SourceFile,Signature,LineNumberTable
混淆配置文件不檢查規則是否重復,如果兩條規則沖突,則采用白名單的,比如設置了開啟優化和不優化兩個選項后,無論順序,最終都會執行不優化的操作。
? ? ? 舉例說明:端內直連jira提bug的避混處理:
? ? ?其中:-dontwarn 不提示指定包名下的所有類的警告
? ? ? ? ? ? ? ? -keep 保留指定包名下所有類,不做混淆處理(這些類就是需要被避混的類,需要被避混的方法也都在這些類中,可以看到這里我對2個不同的包下的所有文件進行了避混處理)