一.相信有不少小伙伴還在為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)一張截圖
注釋?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加固寶有自帶的簽名工具可以一鍵加固簽名
6.加固完成的.apk文件體積會(huì)略有增大,就能直接上傳應(yīng)用市場(chǎng)了范咨。隨手分享故觅,喜歡的朋友可以關(guān)注微信公眾號(hào)MiHomes,后續(xù)會(huì)有更多更好的博客推送給您渠啊。
另:歡迎指出不足输吏,會(huì)進(jìn)行更正
末尾:移動(dòng)互聯(lián)&人力資源交流群,可加微信zy666128入群交流替蛉。