Android多模組混淆、多module混淆、多library混淆的正確姿勢
部落格中我們提到了混淆。混淆的文章其實網上也很多,介紹的都很好,但是關於多個module的混淆規則就不是這麼詳細,有的也是錯誤的,經過了2天的多次實踐以及查閱資料(多次打包和反編譯看原始碼,很費時間啊),終於達到了我的目的。下面來總結一下。也希望能幫到需要的同學。
Android Studio本身集成了ProGuard混淆工具,我們可以通過編輯build.gradle檔案來開啟混淆並且對程式碼進行壓縮,對資源進行優化等。如下圖
下面是程式碼,可以直接複製
buildTypes {
release {
minifyEnabled true //開啟混淆
zipAlignEnabled true //壓縮優化
shrinkResources true //移出無用資源
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' //預設的混淆檔案以及我們指定的混淆檔案
}
}
開啟了混淆別忘去proguard-rules.pro檔案編輯混淆規則,混淆規則網上也有很多,自行百度即可。
如果你的專案只有一個app module,那麼這樣配置混淆就可以了。但是如果你的專案有好幾個module,module之間還是相互依賴的,那麼該怎麼混淆呢?
混淆方法
1)在app module中統一配置混淆規則
我們可以直接在app module中build.gradle檔案配置所有module需要混淆的規則。這樣,其他module中就無需開啟混淆。但是並不推薦使用這種方法,當我們取消依賴某些module的時候,這樣很容易造成混淆規則冗餘,我們還需要刪除掉該module相關的混淆配置,很麻煩。
2)各個module單獨配置混淆規則(推薦)
我們也可以單獨為module配置混淆規則,比較推薦這種做法。每個module管理自己的混淆檔案,當我們不依賴該module的時候,就不會發生第一種方法出現的問題了。
我們把app module稱作為主模組,其依賴的其他module稱作為子模組
如圖所示。我的app模組是依賴了其他模組的,其他模組也有相互依賴的地方。
網上很多關於子module的混淆配置是錯誤的,經過我的多次實踐得出,主模組的混淆開關配置會直接影響到子模組,也就是說如果你的主模組開啟的混淆,就算你的子模組關閉混淆開關,最終子模組還是會被混淆的。
其次
子模組混淆檔案的指定是通過consumerProguardFiles這個屬性來指定的,並不是proguardFiles 屬性,而且我們無需配置其他的選項,只需要配置consumerProguardFiles屬性就可以。該屬性表示在打包的時候會自動尋找該module下我們指定的混淆檔案對程式碼進行混淆。
如果我們釋出出一些開源庫去給別人用,想要對庫程式碼進行混淆的話,也可以通過配置該屬性來達到目的
關於多模組混淆的小技巧
一般來說,在元件化開發的情況下,app module的程式碼是很少的,依賴的第三方庫也是很少的。我們可以把通用的混淆規則放到app module中。 這樣子module就無需配置通用混淆規則,只需要配置一些該module所需要的混淆規則即可。大大減少了混淆程式碼。
app module下的混淆規則
這裡給出一個也是從網上找的基本的混淆模板。關於自己專案的實體類和依賴的第三方sdk需要自己新增混淆規則,一般開源庫都會給出混淆規則,沒有的話就要自己百度了
#
#-------------------------------------------基本不用動區域----------------------------------------------
#
#
# -----------------------------基本 -----------------------------
#
# 指定程式碼的壓縮級別 0 - 7(指定程式碼進行迭代優化的次數,在Android裡面預設是5,這條指令也只有在可以優化時起作用。)
-optimizationpasses 5
# 混淆時不會產生形形色色的類名(混淆時不使用大小寫混合類名)
-dontusemixedcaseclassnames
# 指定不去忽略非公共的庫類(不跳過library中的非public的類)
-dontskipnonpubliclibraryclasses
# 指定不去忽略包可見的庫類的成員
-dontskipnonpubliclibraryclassmembers
#不進行優化,建議使用此選項,
-dontoptimize
# 不進行預校驗,Android不需要,可加快混淆速度。
-dontpreverify
# 遮蔽警告
-ignorewarnings
# 指定混淆是採用的演算法,後面的引數是一個過濾器
# 這個過濾器是谷歌推薦的演算法,一般不做更改
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
# 保護程式碼中的Annotation不被混淆
-keepattributes *Annotation*
# 避免混淆泛型, 這在JSON實體對映時非常重要
-keepattributes Signature
# 丟擲異常時保留程式碼行號
-keepattributes SourceFile,LineNumberTable
#優化時允許訪問並修改有修飾符的類和類的成員,這可以提高優化步驟的結果。
# 比如,當內聯一個公共的getter方法時,這也可能需要外地公共訪問。
# 雖然java二進位制規範不需要這個,要不然有的虛擬機器處理這些程式碼會有問題。當有優化和使用-repackageclasses時才適用。
#指示語:不能用這個指令處理庫中的程式碼,因為有的類和類成員沒有設計成public ,而在api中可能變成public
-allowaccessmodification
#當有優化和使用-repackageclasses時才適用。
#-repackageclasses com.test
# 混淆時記錄日誌(列印混淆的詳細資訊)
# 這句話能夠使我們的專案混淆後產生對映檔案
# 包含有類名->混淆後類名的對映關係
-verbose
#
# ----------------------------- 預設保留 -----------------------------
#
#----------------------------------------------------
# 保持哪些類不被混淆
#繼承activity,application,service,broadcastReceiver,contentprovider....不進行混淆
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.support.multidex.MultiDexApplication
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
-keep class android.support.** {*;}## 保留support下的所有類及其內部類
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
#表示不混淆上面宣告的類,最後這兩個類我們基本也用不上,是接入Google原生的一些服務時使用的。
#----------------------------------------------------
# 保留繼承的
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v7.**
-keep public class * extends android.support.annotation.**
#表示不混淆任何包含native方法的類的類名以及native方法名,這個和我們剛才驗證的結果是一致
-keepclasseswithmembernames class * {
native <methods>;
}
#這個主要是在layout 中寫的onclick方法android:onclick="onClick",不進行混淆
#表示不混淆Activity中引數是View的方法,因為有這樣一種用法,在XML中配置android:onClick=”buttonClick”屬性,
#當用戶點選該按鈕時就會呼叫Activity中的buttonClick(View view)方法,如果這個方法被混淆的話就找不到了
-keepclassmembers class * extends android.app.Activity{
public void *(android.view.View);
}
#表示不混淆列舉中的values()和valueOf()方法,列舉我用的非常少,這個就不評論了
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
#表示不混淆任何一個View中的setXxx()和getXxx()方法,
#因為屬性動畫需要有相應的setter和getter的方法實現,混淆了就無法工作了。
-keep public class * extends android.view.View{
*** get*();
void set*(***);
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
#表示不混淆Parcelable實現類中的CREATOR欄位,
#毫無疑問,CREATOR欄位是絕對不能改變的,包括大小寫都不能變,不然整個Parcelable工作機制都會失敗。
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
# 這指定了繼承Serizalizable的類的如下成員不被移除混淆
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# 保留R下面的資源
-keep class **.R$* {
*;
}
#不混淆資源類下static的
-keepclassmembers class **.R$* {
public static <fields>;
}
# 對於帶有回撥函式的onXXEvent、**On*Listener的,不能被混淆
-keepclassmembers class * {
void *(**On*Event);
void *(**On*Listener);
}
# 保留我們自定義控制元件(繼承自View)不被混淆
-keep public class * extends android.view.View{
*** get*();
void set*(***);
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
#
#----------------------------- WebView(專案中沒有可以忽略) -----------------------------
#
#webView需要進行特殊處理
-keepclassmembers class fqcn.of.javascript.interface.for.Webview {
public *;
}
-keepclassmembers class * extends android.webkit.WebViewClient {
public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.WebViewClient {
public void *(android.webkit.WebView, jav.lang.String);
}
#在app中與HTML5的JavaScript的互動進行特殊處理
#我們需要確保這些js要呼叫的原生方法不能夠被混淆,於是我們需要做如下處理:
-keepclassmembers class com.ljd.example.JSInterface {
<methods>;
}
#(可選)避免Log列印輸出
-assumenosideeffects class android.util.Log {
public static *** v(...);
public static *** d(...);
public static *** i(...);
public static *** w(...);
}
子module下的混淆配置 示例
只需要配置改module需要的混淆規則即可,注意我這裡只是個示例,具體的混淆規則根據你的module來定。
這樣一來,我們就優雅的完成了多module下的混淆配置。
好了,就這些,希望能幫到你。覺得還行的話點個贊呦。
相關推薦
基於maven使用IDEA搭建和部署SpringBoot多模組專案(Multi-Module)
What matters in life is not what happens to you but what you remember and how you remember it. 生命中真正重要的不是你遭遇了什麼,而是你記住了哪些事,又是如
Android開發OA幸運飛艇原始碼出售 - 獲取系統輸入法高度的正確姿勢
問題與解決在Android應用的開發中OA幸運飛艇原始碼出售QQ2952777280【話仙原始碼論壇】hxforum.com,有一些需求需要我們獲取到輸入法的高度,但是官方的API並沒有提供類似的方法,所以我們需要自己來實現。 查閱了網上很多資料,試過以後都不理想。 比如有的方法通過監聽佈局的變化來計算輸
電商、遊戲、旅遊,找對Facebook海外營銷正確姿勢了嗎?
雖然 Facebook 在上週經歷了一輪股價下跌,但這個社交帝國依然堅挺,畢竟它在全球擁有超 20 億活躍使用者,佔世界人口 1/5。 利用 Facebook 平臺來尋找消費者,這是全球很多品牌都玩得溜溜的了。對於中國的品牌及電商、遊戲、旅遊行業,鑑於客觀原因,要玩轉 Facebook
Android多模組混淆、多module混淆、多library混淆的正確姿勢
部落格中我們提到了混淆。混淆的文章其實網上也很多,介紹的都很好,但是關於多個module的混淆規則就不是這麼詳細,有的也是錯誤的,經過了2天的多次實踐以及查閱資料(多次打包和反編譯看原始碼,很費時間啊),終於達到了我的目的。下面來總結一下。也希望能幫到需要的
Android Studio多模組的SDK專案打包和混淆
任務遇到的難點 1.SDK專案多模組,編譯後每個模組自己生成了1個jar包。但是需求是隻對外發佈一個jar包,需要進行合併多個jar包。 2.生成的jar包中因為模組引入了百度地圖定位導致jar包內有不需要的asset檔案雜項 3.多模組的混淆問題 解決方案:
PYTHON自動化Day6-函式多個返回值和匿名函式、列表生成式,三元運算子,os模組,sys模組,時間模組,字典排序,資料庫操作,加密(md5)
一.函式多個返回值和匿名函式 #函式返回多個值,用一個變數接收 def say(): num1=1 num2=2 num3=3 return num1,num2,num3 res=say() print(res) #打印出來是元組。 函式如果返回多個值的話,會把返回的
python學習第34天之udp的套接字、套接字的多執行緒socketserver模組的使用、作業系統理論
一、udp的套接字 Udp協議又叫資料報協議, 特點:每次傳送資料自帶報頭,即使傳送為0也會自帶報頭,所以不會報錯;一端發一次資料。另一端也只能收一次資料 服務端: import socket server=socket.socket(socket.AF_INET,socket.SOCK_DG
SpringBoot專案(單模組、多模組)使用docker容器執行jar包映象(踩坑)
SpringBoot專案(單模組、多模組)使用docker容器執行jar包映象(踩坑) 1.mavem docker外掛配置 <!--docker 外掛配置--> <build> <finalName>生成jar包的名稱</
SpringBoot 多模組專案(module)Service自動注入(@Autowired)空指標錯誤解決
報錯資訊,這個我是截了上一部分,為了省空間下部分我就用...代替了。 java.lang.NullPointerException at com.jd.impl.UploadServiceImpl.uploadBlock(UploadServiceImpl.java:39)
android多框架實現短視訊應用、3D手勢旋轉、banner控制元件、指南針、智慧管家等應用原始碼
Android精選原始碼 android智慧管家app原始碼 Android高仿拼多多分類列表 Android百度地圖例項詳解之仿摩拜單車APP RecyclerView的LayoutManager搭建流式佈局 Android自定義View分享——一個圓形
[java基礎]一文理解java多執行緒必備的ychronized關鍵字,從此不再混淆!
java併發程式設計中最長用到的關鍵字就是synchronized了,這裡講解一下這個關鍵字的用法和容易混淆的地方. synchronized關鍵字涉及到鎖的概念, 在java中,synchronized鎖大家又通俗的稱為:方法鎖,物件鎖 和 類鎖 三種. 先上結論! 1 無論是修飾方法還是修飾程式碼塊都
[java基礎]一文理解java多執行緒必備的sychronized關鍵字,從此不再混淆!
java併發程式設計中最長用到的關鍵字就是synchronized了,這裡講解一下這個關鍵字的用法和容易混淆的地方.synchronized關鍵字涉及到鎖的概念, 在java中,synchronized
解決springboot多模組注入(@Bean、@Service、@Component)訪問不到的問題
如果你因為Service注入失敗,看過無數文章,甚至看過N份原始碼仍不得要領,希望我能終結你的問題; SpringBoot中Service自動注入很方便,例: Service.class(介面類) ServiceImpl.class(實現類) Controller
使用 多渠道productFlavor、多客戶、多版本buildType 、多模組moudle 配置的 那些點點滴滴
------------------------------------------------------------------------------------------------------------------------------------------
idea建立多模組Springboot專案、匯入多模組、刪除多模組
前言 在eclipse中有Workspace(工作空間)和 Project(工程)的概念在 IDEA中只有 Project(工程)和 Module(模組)的概念。這個地方剛開始用的時候會很容易理不清
MySQL:記錄的增刪改查、單表查詢、約束條件、多表查詢、連表、子查詢、pymysql模組、MySQL內建功能
資料操作 插入資料(記錄): 用insert; 補充:插入查詢結果: insert into 表名(欄位1,欄位2,...欄位n) select (欄位1,欄位2,...欄位n) where ...; 更新資料update 語法: update 表名 set 欄位1=
IO模型——阻塞IO、非阻塞IO、多路複用IO、非同步IO、selectors模組
目錄 一、IO模型介紹 為了更好地瞭解IO模型,我們需要事先回顧下:同步、非同步、阻塞、非阻塞 同步(synchronous) IO和非同步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blo
一個 Yii + vue 專案(6)yii模型、多模組登陸
簡單講一下模型,之前介紹的AR類全稱是(ActiveRecord 在yii\db\ActiveRecord)用中文描述是活動記錄,是一種特殊的模型,模型呢,是 mvc 裡的 m,yii的模型(yii\base\Model)內建了一些常用的處理,像場景,驗證,載入資料,輸出處理。。。這裡就
kotlin和java混合開發專案,多模組,分模組開發,分module,元件化開發
# picture_dx #歡迎能來到這裡 客服機器人美洽第三方完美接入魔窗 該demo用了元件化 為什麼要元件化 近年來,為什麼這麼多團隊要進行元件化實踐呢?元件化究竟能給我們的工程、程式碼帶來什麼好處?我們認為元件化能夠帶來兩個最大的好處: 提高元件複用
Android常見多條件篩選選單(美團、58)
1.簡單實現 1.1佈局分析: 自定義ListPopuScreenMenuView 繼承自 LinearLayout,大致分為三個部分:上面頭部TabLinearLayout;中間的選單內容menuContainerFrameLayout;下面的半透