1、集成了友盟统计,并在AndroidManifest.xml中添加了如下代码
<meta-data
android:name="UMENG_CHANNEL"
android:value="${CHANNEL_VALUE}"/>
2、在app的build.gradle的android标签下添加如下代码:
productFlavors {
myapp {}
_360 {}
appchina {}
hiapk {}
}
productFlavors.all {
flavor -> flavor.manifestPlaceholders = [CHANNEL_VALUE: name]
}
3、检查是否配置了gradle PATH环境变量,命令行下执行gradle -v,如果不能识别则到AndroidStudio的安装目录下找到gradle目录,把其下的bin目录添加到Path中,然后执行如下命令:
gradle assembleRelease
坐等编译打包成功,不知道是不是我第一次用的原因,执行完这个命令后一直在download什么东西,过了大概四五分钟,开始打包不同渠道的apk了,最终如下图所示:
以上这是通过命令行打包,当然也可以直接通过UI方式,选择菜单Build–>Generate Signed APK–>选择创建好的密钥keystore(没有就创建一个),然后点击Next就会弹出如下图所示的对话框:
这里也可以选择渠道或者build type,Flavors最少选择一个,点击Finish同样可以多渠道打包。
感慨一下:以前使用Eclipse多渠道打包的时候感觉好麻烦,现在AS的多渠道打包感觉好方便快捷。
1、把build.gradle中的buildTypes下的 minifyEnable置为true
2、编辑app目录下的proguard-rules.pro文件如下:
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in E:\AndroiSdK/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
#----------------通用混淆Start---------------------
-optimizationpasses 5 # 指定代码的压缩级别 -dontusemixedcaseclassnames # 是否使用大小写混合 -dontpreverify # 混淆时是否做预校验 -verbose # 混淆时是否记录日志
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # 混淆时所采用的算法
-keep public class * extends android.app.Activity # 保持哪些类不被混淆 -keep public class * extends android.app.Application # 保持哪些类不被混淆 -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 com.android.vending.licensing.ILicensingService # 保持哪些类不被混淆
-keepclasseswithmembernames class * { # 保持 native 方法不被混淆 native <methods>;
}
-keepclasseswithmembers class * { # 保持自定义控件类不被混淆 public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {# 保持自定义控件类不被混淆 public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity { # 保持自定义控件类不被混淆 public void *(android.view.View);
}
-keepclassmembers enum * { # 保持枚举 enum 类不被混淆 public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable { # 保持 Parcelable 不被混淆 public static final android.os.Parcelable$Creator *;
}
#----------------通用混淆End---------------------
#----------------友盟5.0混淆Start---------------------
-dontshrink -dontoptimize -dontwarn com.google.android.maps.** -dontwarn android.webkit.WebView -dontwarn com.umeng.** -dontwarn com.tencent.weibo.sdk.** -dontwarn com.facebook.**
-keep enum com.facebook.** -keepattributes Exceptions,InnerClasses,Signature -keepattributes *Annotation* -keepattributes SourceFile,LineNumberTable
-keep public interface com.facebook.** -keep public interface com.tencent.** -keep public interface com.umeng.socialize.** -keep public interface com.umeng.socialize.sensor.** -keep public interface com.umeng.scrshot.**
-keep public class com.umeng.socialize.* {*;} -keep public class javax.** -keep public class android.webkit.**
-keep class com.facebook.** -keep class com.facebook.** { *; } -keep class com.umeng.scrshot.** -keep public class com.tencent.** {*;} -keep class com.umeng.socialize.sensor.** -keep class com.umeng.socialize.handler.** -keep class com.umeng.socialize.handler.* -keep class com.tencent.mm.sdk.modelmsg.WXMediaMessage {*;} -keep class com.tencent.mm.sdk.modelmsg.** implements com.tencent.mm.sdk.modelmsg.WXMediaMessage$IMediaObject {*;}
-keep class im.yixin.sdk.api.YXMessage {*;} -keep class im.yixin.sdk.api.** implements im.yixin.sdk.api.YXMessage$YXMessageData{*;}
-dontwarn twitter4j.** -keep class twitter4j.** { *; }
-keep class com.tencent.** {*;} -dontwarn com.tencent.** -keep public class com.umeng.soexample.R$*{ public static final int *;
}
-keep public class com.umeng.soexample.R$*{ public static final int *;
}
-keep class com.tencent.open.TDialog$* -keep class com.tencent.open.TDialog$* {*;} -keep class com.tencent.open.PKDialog -keep class com.tencent.open.PKDialog {*;} -keep class com.tencent.open.PKDialog$* -keep class com.tencent.open.PKDialog$* {*;}
-keep class com.sina.** {*;} -dontwarn com.sina.** -keep class com.alipay.share.sdk.** { *;
}
-keepnames class * implements android.os.Parcelable { public static final ** CREATOR;
}
-keep class com.linkedin.** { *; } -keepattributes Signature #----------------友盟5.0混淆End---------------------
#----------------高德地图混淆Start---------------------
-dontwarn com.amap.api.mapcore2d.** #定位
-keep class com.amap.api.location.**{*;} -keep class com.amap.api.fence.**{*;} -keep class com.autonavi.aps.amapapi.model.**{*;}
#搜索
-keep class com.amap.api.services.**{*;}
#2D地图
-keep class com.amap.api.maps2d.**{*;} -keep class com.amap.api.mapcore2d.**{*;} #----------------高德地图混淆End---------------------
#----------------极光推送混淆Start---------------------
-dontoptimize -dontpreverify
-dontwarn cn.jpush.** -keep class cn.jpush.** { *; } #gson
-dontwarn com.google.** -keep class com.google.gson.** {*;}
#protobuf
-dontwarn com.google.** -keep class com.google.protobuf.** {*;} #----------------极光推送混淆End---------------------
#----------------Mob短信验证混淆Start---------------------
-keep class android.net.http.SslError -keep class android.webkit.**{*;} -keep class cn.sharesdk.**{*;} -keep class cn.smssdk.**{*;} -keep class com.mob.**{*;} #----------------Mob短信验证混淆End---------------------
代码虽然多,但也很容易明白,首先通用混淆一定要有(参考Android Studio实现代码混淆),其他的就根据项目里添加了哪些第三方库就到第三方开发者平台下找到他们提供的混淆内容即可
a.如果混淆打包成功后,应用跑起来报了如下图的错误:
那肯定是因为没有添加Mob短信验证的混淆代码,因为在他们官方的集成文档里没提到,不过去论坛里倒是找到了解答,就如上面代码最后一段。
b.如果数据的封装用到了Gson,那么也要添加混淆,包括项目中所有的javaBean,也就是实体类,混淆代码如下(可参考官方Github说明):
##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
#-keep class com.google.gson.examples.android.model.** { *; }
##---------------End: proguard configuration for Gson ----------
-keep class com.xxx.xxxxxxxxx.bean.** { *; } # 保持项目中的实体类不被混淆
c.如果你的项目中集成了MPAndroidChart图表,那么也得加上混淆,参考这里,代码如下:
-keep class com.github.mikephil.charting.** { *; } # 确保MPAndroidChart加载动画可用
d.如果你的项目中使用了Webview并且自定义了Javainterface有js交互的,那么需要添加如下混淆代码:
#----------------JS混淆Start---------------------
-keepclassmembers class com.xxxxx.xxx.xxxActivity$MyJavaScriptInterface { public *;
}
-keepattributes *Annotation* -keepattributes *JavascriptInterface* #----------------JS混淆End---------------------
3、执行打包即可
4、对打包所得apk用dex2jar以及jdgui反编译后,查看java源码,发现确实有很多文件被混淆了。
说到底,批量打包和代码混淆在Eclipse和Android Studio两个IDE下都是差不多的。之前还写过两篇关于这方面的博客,Android代码混淆的使用,Ant批量打包工具的使用,现在再看以前写的,还是有点用的。