一乌叶、混淆的概念
將Android項目進行打包之時准浴,可以將項目里的包名乐横、類名今野、變量名進行更改条霜,使得代碼不容易泄露,類似于對其apk中的文件加密。
二蒲凶、混淆的作用
? ? ? ?首先,大家要知道宠默,Android項目直接打成apk包之后灵巧,其實是可以通過一定的反編譯技術手段看到apk中的源碼孩等,這對于一些商業(yè)項目(非開源項目)來說采够,肯定是不合適的,而“混淆”可以一定程度的避免apk被簡單的反編譯权她,從而被其他人窺視到apk包中的奧秘隅要。
? ? ? ?所以董济,簡而言之虏肾,混淆的作用:
? ? ? ? ? ?1.?代碼混淆后閱讀性降低,反編譯后破譯程序難度提高谴轮;
? ? ? ? ? ?2. 混淆后字節(jié)數(shù)減少第步,減少了應用了體積
三缘琅、什么是混淆,什么是避混
? ? ? ?Android SDK 本身就提供混淆的功能驯杜,將混淆開關進行開啟后(下文會舉例說明如何開啟)鸽心,開發(fā)者需要做的是對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):默認開啟纱烘,用以減小應用體積,移除未被使用的類和成員擂啥,并且會在優(yōu)化動作執(zhí)行之后再次執(zhí)行(因為優(yōu)化后可能會再次暴露一些未被使用的類和成員)哺壶。
? ? ? ? ? ? ? ? ? ? 關閉壓縮的方法:-dontshrink
? ? ? ? ?公司App中变骡,采用的是開啟壓縮芭逝。
2.優(yōu)化(Optimization):默認開啟,在字節(jié)碼級別執(zhí)行優(yōu)化旬盯,讓應用運行的更快胖翰。
? ? ? ? ? ? ? ? ? ?關閉優(yōu)化的方法:-dontoptimize 關閉優(yōu)化
? ? ? ? 使用方法:-optimizationpasses n 表示proguard對代碼進行迭代優(yōu)化的次數(shù)萨咳,Android一般為5
? ? ? ? ? ? ? ? ? ?公司App中,采用了優(yōu)化培他,且該值為5舀凛。
3.混淆(Obfuscation):默認開啟猛遍,增大反編譯難度,類和類成員會被隨機命名梯醒,除非用keep保護腌紧。
? ? ? ? ? ? ? ? ? ? 關閉混淆的方法:-dontobfuscate 關閉混淆
? ? ? ? ?公司App中寄啼,開啟了混淆,混淆的具體內容涕刚,就在proguard-project.txt中乙帮。
? ? ? ?本文主要針對混淆進行簡單講解察净。
五、怎么實現(xiàn)混淆
? ? ? ? 以公司App舉例說明氢卡。
? ? ? ? 首先,在appmodule的build.gradle文件中峡捡,能看到:
? ? ? ? ?說明一下:
? ? ? ? ? ? ? ?1. 此處的release代表打release包時用的配置內容们拙,debug為打debug包時用的配置內容砚婆,dev為打dev包時用到的配置內容装盯。
2.minifyEnabled?false?代表不開啟混淆与境;minifyEnabled?true 代表開啟混淆
開啟混淆后摔刁,可以添加:shrinkResources?true?代表去掉沒有引用的資源,可以減少應用的體積绑谣,但這個只有在混淆開啟后才有效借宵。
? ? ? ? ? ?從圖中可以明顯看到,debug雖然配置了混淆文件豁护,但沒有開啟混淆楚里;release猎贴、dev都開啟了混淆她渴,且混淆文件都為同一份:proguard-project.txt趁耗,該文件在上面的(二)中,已經(jīng)截圖給出來了右冻。打開文件就能看到具體的內容著拭。
? ? ? ? ? ?另外再做個說明牍帚,大家如果細心的話暗赶,應該會發(fā)現(xiàn)在上面(二)的截圖中蹂随,能看到不僅有proguard-project.txt,還有proguard-gen.txt绩衷、proguard-rn.txt,其實這2個文件都被包含在了proguard-project.txt中:
? ? ? ? 打開這兩個文件,會發(fā)現(xiàn)文件內容的格式與proguard-project.txt文件一致低缩,不用懷疑,這兩個其實也是混淆文件咆繁。公司App根據(jù)各類和包的不同作用么介,將內容寫在了不同的proguard文件中蜕衡。
? ? ? ? 項目編譯的時候慨仿,會先找到proguard-project.txt執(zhí)行,之后執(zhí)行的過程中帘撰,會將include進來的2個proguard文件一并做處理。
混淆后默認會在工程目錄app/build/outputs/mapping/release下生成一個mapping.txt文件万皿,這就是混淆規(guī)則摧找,我們可以根據(jù)這個文件把混淆后的代碼反推回源本的代碼,所以這個文件很重要牢硅,注意保護好蹬耘。原則上,代碼混淆后越亂越無規(guī)律越好减余,但有些地方我們是要避免混淆的综苔,否則程序運行就會出錯,所以就有了下面要說的:如何讓自己的部分代碼避免混淆從而防止出錯位岔。
六如筛、如何避混
? ? ? 需要避混的文件都需要一一添加到proguard文件中,先給出兩份比較全的混淆指令相關博客鏈接:
http://blog.csdn.net/yk377657321/article/details/60501880
http://blog.csdn.net/maxwell_nc/article/details/51998766
? ? ? 針對公司App中用到的語法抒抬,進行簡單說明:
1杨刨、# 代表行注釋符
2妖胀、-?表示一條規(guī)則的開始
3浇借、keep 保留肉康,例如keepattributes:表示保留屬性
4涨薪、dont 不要,例如dontwarn:表示不要提示警告
5侠姑、ignore 忽略邦邦,例如ignorewarning:表示忽略警告
6、-dontoptimize不優(yōu)化 薪韩,值得注意的是默認混淆配置文件開啟了-dontoptimize
7观谦、-assumenosideeffects?關閉log
8捉偏、一般混淆規(guī)則都要加入谊路,其中前兩個在默認文件中已經(jīng)配置:
8.1潮梯、-dontusemixedcaseclassnames?包名不使用大小寫混合?aA Aa ? ?公司App中未開啟
8.2脱羡、-dontskipnonpubliclibraryclasses不混淆第三方引用的庫?公司App中未開啟
? ? ? ? ? ? ? ? ? ? ? ??8.3、-dontpreverify不做預校驗公司App中已開啟
? ? ? ? ? ? ? ? ? ? ? ? 8.4馆揉、?-ignorewarning忽略警告公司App中未開啟
? ? ? ? ? ? ?9、輸出混淆記錄:
9.1、-verbose混淆后生產(chǎn)映射文件 map 類名->轉化后類名的映射,存放在app\build\outputs\mapping\release中
9.2凿菩、-printmapping混淆前后的映射似将,公司App中是:out.map
10堵未、保留原代碼行號:-keepattributes?拋出異常時保留代碼行號耻陕,這個最后release的時候關閉掉,公司App中是:Exceptions,SourceFile,Signature,LineNumberTable
混淆配置文件不檢查規(guī)則是否重復,如果兩條規(guī)則沖突忘古,則采用白名單的娘荡,比如設置了開啟優(yōu)化和不優(yōu)化兩個選項后,無論順序,最終都會執(zhí)行不優(yōu)化的操作轻要。
? ? ? 舉例說明:端內直連jira提bug的避混處理:
? ? ?其中:-dontwarn 不提示指定包名下的所有類的警告
? ? ? ? ? ? ? ? -keep 保留指定包名下所有類柏蘑,不做混淆處理(這些類就是需要被避混的類咳焚,需要被避混的方法也都在這些類中,可以看到這里我對2個不同的包下的所有文件進行了避混處理)