Android APK 混淆 簽名 打包 加固 重簽名 全流程

一.相信有不少小伙伴還在為Apk上架應(yīng)用市場(chǎng)而苦惱吧鱼喉,現(xiàn)在就分享一下apk從代碼變?yōu)榭缮蟼鲬?yīng)用市場(chǎng)的安裝包的詳細(xì)流程,仔細(xì)閱讀,相信您會(huì)有收獲左医。

1.配置混淆文件(Android studio對(duì)應(yīng)module下的 proguard-rules.pro文件):混淆文件主要分為三部分,一部分為固定的配置代碼同木,一部分為你不想要混淆的自定義Application類(lèi)或者網(wǎng)絡(luò)請(qǐng)求基類(lèi)浮梢,另一部分為你使用的所有第三方插件的混淆代碼。

----------------------------------------------------------------我是小坑分割線(xiàn)----------------------------------------------------------------------------
插播一則廣告彤路,gson類(lèi)也要防混淆秕硝,第三方實(shí)體類(lèi)和自己的自定義控件類(lèi)也要防混淆,切記~
----------------------------------------------------------------我是小坑分割線(xiàn)----------------------------------------------------------------------------
A.固定的配置代碼洲尊,同時(shí)要做禁LOG處理(即在你proguard-android.txt中一定不要加-dontoptimize才起作用):

        # 代碼混淆壓縮比远豺,在0~7之間,默認(rèn)為5坞嘀,一般不做修改
        -optimizationpasses 5

        # 混合時(shí)不使用大小寫(xiě)混合躯护,混合后的類(lèi)名為小寫(xiě)
        -dontusemixedcaseclassnames

        # 指定不去忽略非公共庫(kù)的類(lèi)
        -dontskipnonpubliclibraryclasses

        # 這句話(huà)能夠使我們的項(xiàng)目混淆后產(chǎn)生映射文件
        # 包含有類(lèi)名->混淆后類(lèi)名的映射關(guān)系
        -verbose
        
        # 指定不去忽略非公共庫(kù)的類(lèi)成員
        -dontskipnonpubliclibraryclassmembers

        # 不做預(yù)校驗(yàn),preverify是proguard的四個(gè)步驟之一姆吭,Android不需要preverify榛做,去掉這一步能夠加快混淆速度。                                          
        -dontpreverify

        # 保留Annotation不混淆
       -keepattributes *Annotation*,InnerClasses

       # 避免混淆泛型
       -keepattributes Signature

       # 拋出異常時(shí)保留代碼行號(hào)
       -keepattributes SourceFile,LineNumberTable

       # 指定混淆是采用的算法内狸,后面的參數(shù)是一個(gè)過(guò)濾器
       # 這個(gè)過(guò)濾器是谷歌推薦的算法检眯,一般不做更改
       -optimizations !code/simplification/cast,!field/*,!class/merging/*


       #############################################
       #
       # Android開(kāi)發(fā)中一些需要保留的公共部分
       #
       #############################################

       # 保留我們使用的四大組件,自定義的Application等等這些類(lèi)不被混淆
       # 因?yàn)檫@些子類(lèi)都有可能被外部調(diào)用
       -keep public class * extends android.app.Activity
       -keep public class * extends android.app.Appliction
       -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 public class com.android.vending.licensing.ILicensingService


       # 保留support下的所有類(lèi)及其內(nèi)部類(lèi)
       -keep class android.support.** {*;}

       # 保留繼承的
       -keep public class * extends android.support.v4.**
       -keep public class * extends android.support.v7.**
       -keep public class * extends android.support.annotation.**

       # 保留R下面的資源
       -keep class **.R$* {*;}

       # 保留本地native方法不被混淆
       -keepclasseswithmembernames class * {
           native <methods>;
       }

       # 保留在Activity中的方法參數(shù)是view的方法昆淡,
       # 這樣以來(lái)我們?cè)趌ayout中寫(xiě)的onClick就不會(huì)被影響
       -keepclassmembers class * extends android.app.Activity{
           public void *(android.view.View);
       }

       # 保留枚舉類(lèi)不被混淆
       -keepclassmembers enum * {
           public static **[] values();
           public static ** valueOf(java.lang.String);
       }

       # 保留我們自定義控件(繼承自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);
       }

       # 保留Parcelable序列化類(lèi)不被混淆
       -keep class * implements android.os.Parcelable {
           public static final android.os.Parcelable$Creator *;
       }

       # 保留Serializable序列化的類(lèi)不被混淆
       -keepclassmembers class * implements java.io.Serializable {
           static final long serialVersionUID;
           private static final java.io.ObjectStreamField[] serialPersistentFields;
           !static !transient <fields>;
           !private <fields>;
           !private <methods>;
           private void writeObject(java.io.ObjectOutputStream);
           private void readObject(java.io.ObjectInputStream);
           java.lang.Object writeReplace();
           java.lang.Object readResolve();
       }

       # 對(duì)于帶有回調(diào)函數(shù)的onXXEvent锰瘸、**On*Listener的,不能被混淆
       -keepclassmembers class * {
           void *(**On*Event);
           void *(**On*Listener);
       }

       # webView處理昂灵,項(xiàng)目中沒(méi)有使用到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);
       }
       
       # 移除Log類(lèi)打印各個(gè)等級(jí)日志的代碼避凝,打正式包的時(shí)候可以做為禁log使用舞萄,這里可以作為禁止log打印的功能使用  
       # 記得proguard-android.txt中一定不要加-dontoptimize才起作用
       # 另外的一種實(shí)現(xiàn)方案是通過(guò)BuildConfig.DEBUG的變量來(lái)控制
      -assumenosideeffects class android.util.Log {
          public static int v(...);
          public static int i(...);
          public static int w(...);
         public static int d(...);
         public static int e(...);
      }          

B.你不想混淆的實(shí)體類(lèi)(注:doudou.soga.com.doudou為你的包名,bean為對(duì)應(yīng)的文件夾名字管削,** { ; }代表該文件夾下的所有類(lèi)):
#--------------------------2.實(shí)體類(lèi)---------------------------------
-keep class doudou.soga.com.doudou.bean.
* { ; } #實(shí)體類(lèi)不參與混淆
-keep class doudou.soga.com.doudou.widget.
* { ; } #自定義控件不參與混淆
-keep class doudou.soga.com.doudou.app.
* { *; } #網(wǎng)絡(luò)請(qǐng)求和自定義Applicattion類(lèi)不參與混淆

C.第三方控件混淆代碼(這些代碼都可以百度Copy到倒脓,為你使用的所有第三方插件的混淆代碼。我就隨便列一兩個(gè)):

      #--------------------------3.第三方包-------------------------------
      
      ################gson##################
      -keep class com.google.gson.** {*;}
      #-keep class com.google.**{*;}
      -keep class sun.misc.Unsafe { *; }
      -keep class com.google.gson.stream.** { *; }
      -keep class com.google.gson.examples.android.model.** { *; }
      -keep class com.google.** {
          <fields>;
          <methods>;
      }
      -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();
      }
      -dontwarn com.google.gson.**

       ####################jpush##################
      -keep class cn.jpush.** { *; }
      -keep public class com.umeng.fb.ui.ThreadView { } #雙向反饋功能代碼不混淆
      -dontwarn cn.jpush.**
      -keepclassmembers class * {
          public <init>(org.json.JSONObject);
      }
       -keep public class cn.jiguang.analytics.android.api.** {
              *;
          }
       #不混淆R類(lèi)
      -keep public class com.jph.android.R$*{
          public static final int *;
      }
      -keepclassmembers enum * {
          public static **[] values();
          public static ** valueOf(java.lang.String);
      }

      ################ButterKnife###################
          -keep class butterknife.** { *; }
          -dontwarn butterknife.internal.**
          -keep class **$$ViewBinder { *; }

          -keepclasseswithmembernames class * {
              @butterknife.* <fields>;
          }

          -keepclasseswithmembernames class * {
              @butterknife.* <methods>;
          }

2.接著含思,那么就要修改module下的build.gradle的minifyEnabled 為T(mén)rue

       android{ 
          buildTypes {
              release {
                     minifyEnabled true    //注意崎弃,在這里!:恕K亲觥!
                     proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                 }
             }
         }    

3.混淆文件配置好了遏弱,那么可以開(kāi)始簽名打包了盆均。若是多渠道打包,(我采用的是JPUSH),那么還要在清單文件AndroidManifest.xml最底層配置這一行代碼(meizu-market代表魅族應(yīng)用市場(chǎng)漱逸,JPUSH統(tǒng)計(jì)代碼請(qǐng)參閱極光官方文檔):

    <!-- JPUSH_CHANNEL 是為了方便開(kāi)發(fā)者統(tǒng)計(jì)APK分發(fā)渠道泪姨。-->
    <!-- 例如: -->
    <!-- 發(fā)到 Google Play 的APK可以設(shè)置為 google-play; -->
    <!-- 發(fā)到其他市場(chǎng)的 APK 可以設(shè)置為 xxx-market。 -->
    <!-- 渠道統(tǒng)計(jì)報(bào)表位于控制臺(tái)頁(yè)面的 “統(tǒng)計(jì)”-“用戶(hù)統(tǒng)計(jì)”-“渠道分布” 中-->
    <meta-data android:name="JPUSH_CHANNEL" android:value="meizu-market"/>

4.正式開(kāi)始打包虹脯,首先Android Studio --Build -- Generate Signed APK ,然后配置你的簽名信息驴娃,下一步直接打包就行拉。附贈(zèng)一張截圖

圖片.png

注釋?zhuān)?br> Key store path:簽名文件配置的路徑+名字
Password:密碼(每次簽名都要輸入的循集,后面也可以記住密碼)
Confirm:確認(rèn)密碼
Alias:別名
Validity:簽名有效時(shí)間
Certificate:證書(shū)
First and Last Name:開(kāi)發(fā)者名字
Organizational Unit:組織單位
Organization:組織
City or Locality:城市或地區(qū)
State or Province:州或省
Country Code(xx):中國(guó)可填86

5.打包完成以后,在項(xiàng)目路徑下會(huì)生成一個(gè).apk文件(注:DouDou為項(xiàng)目名蔗草,app為module名)咒彤,然后可以直接下載360加固寶加固(注:加固完成以后需要重新簽名一次才能安裝!V渚O庵!DP稹)歇拆,360加固寶有自帶的簽名工具可以一鍵加固簽名

圖片.png
圖片.png

6.加固完成的.apk文件體積會(huì)略有增大,就能直接上傳應(yīng)用市場(chǎng)了范咨。隨手分享故觅,喜歡的朋友可以關(guān)注微信公眾號(hào)MiHomes,后續(xù)會(huì)有更多更好的博客推送給您渠啊。

另:歡迎指出不足输吏,會(huì)進(jìn)行更正

末尾:移動(dòng)互聯(lián)&人力資源交流群,可加微信zy666128入群交流替蛉。


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贯溅,一起剝皮案震驚了整個(gè)濱河市拄氯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌它浅,老刑警劉巖译柏,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異姐霍,居然都是意外死亡艇纺,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)邮弹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)黔衡,“玉大人,你說(shuō)我怎么就攤上這事腌乡∶私伲” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵与纽,是天一觀的道長(zhǎng)侣签。 經(jīng)常有香客問(wèn)我,道長(zhǎng)急迂,這世上最難降的妖魔是什么影所? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮僚碎,結(jié)果婚禮上猴娩,老公的妹妹穿的比我還像新娘。我一直安慰自己勺阐,他們只是感情好卷中,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著渊抽,像睡著了一般蟆豫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上懒闷,一...
    開(kāi)封第一講書(shū)人閱讀 52,441評(píng)論 1 310
  • 那天十减,我揣著相機(jī)與錄音,去河邊找鬼愤估。 笑死帮辟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的灵疮。 我是一名探鬼主播织阅,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼震捣!你這毒婦竟也來(lái)了荔棉?” 一聲冷哼從身側(cè)響起闹炉,我...
    開(kāi)封第一講書(shū)人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎润樱,沒(méi)想到半個(gè)月后渣触,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡壹若,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年嗅钻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片店展。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡养篓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赂蕴,到底是詐尸還是另有隱情柳弄,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布概说,位于F島的核電站碧注,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏糖赔。R本人自食惡果不足惜萍丐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一疲迂、第九天 我趴在偏房一處隱蔽的房頂上張望饿敲。 院中可真熱鬧,春花似錦膛堤、人聲如沸刻撒。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)声怔。三九已至,卻和暖如春舱呻,著一層夾襖步出監(jiān)牢的瞬間醋火,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工箱吕, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留芥驳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓茬高,卻偏偏與公主長(zhǎng)得像兆旬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子怎栽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容