最近遇到项目从Eclispe迁移到Android studio,以前的Ant自动打包脚本已经兼容不好了,所以用了Gradle实现打渠道包,切换环境等。
gradle的加入配置便宜版本报名,签名文件,配置打包生成apk文件名称规则,配置url,配置渠道所有的配置都是android {}中只进行的,配置一些关于android的基本配置。
温馨提示:代码部分可以左右滑动查看全部。
配置依赖资源
代码语言:javascript复制 dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs') testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:support-v4:23.2.1'
compile 'com.android.support:recyclerview-v7:23.2.1'
.....
}
如果想兼容v4
代码语言:javascript复制 compile ('com.android.support:recyclerview-v7:22.2.0'){ exclude module: 'support-v4' }
加载签名
代码语言:javascript复制signingConfigs {
release {
keyAlias props['KEY_ALIAS']
keyPassword props['KEY_PASSWORD']
storeFile file(props['KEYSTORE_FILE'])
storePassword props['KEYSTORE_PASSWORD']
}
debug {
storeFile file('../../debug.keystore')
storePassword 'you pass'
keyAlias 'you key'
keyPassword 'you pass'
}
}
加载签名配置文件
代码语言:javascript复制Properties props = new Properties()
props.load(new FileInputStream(file("signing.properties")))
签名文件 signing.properties 配置如下:
代码语言:javascript复制 KEY_ALIAS = xxxx
KEY_PASSWORD = 你的密码
KEYSTORE_FILE = ../../nide.keystroe (相对路径)
KEYSTORE_PASSWORD =密码
签名你自己可生成,可以直接用eclispe生成的。
定义环境
定义线上环境Url
代码语言:javascript复制def host_url = "https://xxx.com";
一些开关
开启混淆开关:
代码语言:javascript复制minifyEnabled true
开启过滤非引用资源打包 :
代码语言:javascript复制shrinkResources true
打开log输出:可以用field自定义属性,这里可以加个是否是debug,这样java代码可以直接用这个属性来做是否输出Log了。
代码语言:javascript复制 buildConfigField "boolean", "LOG_DEBUG", "true"
定义打包方式:
代码语言:javascript复制buildTypes {
release {
minifyEnabled true
shrinkResources true
buildConfigField "boolean", "LOG_DEBUG", "false"
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
minifyEnabled true
shrinkResources true
buildConfigField "boolean", "LOG_DEBUG", "true"
signingConfig signingConfigs.debug
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
编译项目后 会生成buildConfig文件
代码语言:javascript复制 public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true"); // app id
public static final String APPLICATION_ID = "com.skay.test"; public static final String BUILD_TYPE = "debug"; // 渠道
public static final String FLAVOR = "dev"; // 版本
public static final int VERSION_CODE = 1; public static final String VERSION_NAME = "1.0"; // Fields from the variant
public static final String APP_ENV = "dev "; // host
public static final String HOST_URL = " http://aaa.com/"; // Fields from build type: debug
public static final boolean LOG_DEBUG = true;
}
代码中可以用Buidconfig.xxx的变量做一些逻辑判断。
配置打包脚本
可以定制化格式,在输出的apk加上渠道,时间,版本环境等。
代码语言:javascript复制// 指定输出的apk名applicationVariants.all {
variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
// 打包类型
def buildTypeName = variant.buildType.name
if (outputFile != null && outputFile.name.endsWith('.apk')) { // 包名称
def flavorName = variant.productFlavors[0].name
// 版本名称
def versionName = defaultConfig.versionName
// 开发环境
buildConfigField "String", "APP_ENV", ""${flavorName} ""
// 修改打包环境的url
buildConfigField "String", "HOST_URL", "" ${host_url}""
// yourapkname_release_myapk_ver1.0.0_build20130312.apk 输出格式
def fileName = "${PRODUCT_NAME}_${buildTypeName}_${flavorName}_env${flavorName}_ver${versionName}_build${BUILD_TIME_FORMAT}.apk"
output.outputFile = new File(outputFile.parent, fileName)
}
}
}
渠道配置
渠道用Flavors函数控制,可对应添加一些渠道。
代码语言:javascript复制 //修改渠道号
productFlavors { // 线上版本
release{
} //开发版本,
dev {
host_url = "http://xxxx1.com./"
} //Qa测试版本
qa{
host_url = "http://xxx2.com/"
}
}
这样我们在打包时 只要你开启你要的那个版本,buildConfig将会修改,输出包就可以了, 不仅切换了Url,而且还制定了渠道版本,非常方便。
添加对jar的支持
代码语言:javascript复制有时候从eclispe移植过来时,返现jar无法加载,找不到地址
在android {}加入以下配置
代码语言:javascript复制 sourceSets {
main {
jniLibs.srcDir 'libs'
} // Move the tests to tests/java, tests/res, etc...
instrumentTest.setRoot('tests') // Move the build types to build-types/<type>
// For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
// This moves them out of them default location under src/<type>/... which would
// conflict with src/ being used by the main source set.
// Adding new build types or product flavors should be accompanied
// by a similar customization.
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
添加NDK的兼容
如果so找不到 请配置对四个不同cpu的支持
在android {}加入以下配置
代码语言:javascript复制 defaultConfig {
.......
ndk {
abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
}
}
配置混淆
配置proguard-rules.pro文件
代码语言:javascript复制 # 混淆时不使用大小写混合,混淆后的类名为小写# windows下的同学还是加入这个选项吧(windows大小写不敏感)-dontusemixedcaseclassnames# 如果应用程序引入的有jar包,并且想混淆jar包里面的class-dontskipnonpubliclibraryclasses# 指定不去忽略非公共的库的类的成员-dontskipnonpubliclibraryclassmembers# 有了verbose这句话,混淆后就会生成映射文件# 包含有类名->混淆后类名的映射关系# 然后使用printmapping指定映射文件的名称
-verbose
-ignorewarnings # Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).
# 不做预检验,preverify是proguard的四个步骤之一
# Android不需要preverify,去掉这一步可以加快混淆速度-dontpreverify# If you want to enable optimization, you should include the following:# 混淆采用的算法
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*# 设置混淆的压缩比率 0 ~ 7-optimizationpasses 5-allowaccessmodification# 保护代码中的Annotation不被混淆# 这在JSON实体映射时非常重要,比如fastJson-keepattributes *Annotation*# 避免混淆泛型
# 这在JSON实体映射时非常重要,比如fastJson
-keepattributes Signature # 抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable # Add any project specific keep options here:
# 保留了继承自Activity、Application这些类的子类
# 因为这些子类有可能被外部调用
# 比如第一行就保证了所有Activity的子类不要被混淆
-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.view.View-keep public class * extends android.app.backup.BackupAgent
-keep public class * extends android.app.backup.BackupAgentHelper-keep public class * extends android.preference.Preference-keep public class * extends android.support.v4.app.Fragment-keep public class * extends android.app.Fragment-keep public class com.android.vending.licensing.ILicensingService# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native# 所有native的方法不能去混淆.
-keepclasseswithmembernames class * {
native <methods>;
}# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations# 枚举类不能去混淆-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}# 某些构造方法不能去混淆-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}# aidl文件不能去混淆.# 保留Parcelable序列化的类不能被混淆-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}# 保留Serializable 序列化的类不被混淆-keep class * implements java.io.Serializable {
public *;
}
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}# 保留Activity中的方法参数是view的方法,# 从而我们在layout里面编写onClick就不会影响-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}# 保留自定义控件(继承自View)不能被混淆-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(...);
public void get*(...);
} # 对R文件下的所有类及其方法,都不能被混淆
-keepclassmembers class **.R$* {
*;
} # 对于带有回调函数onXXEvent的,不能混淆
-keepclassmembers class * {
void *(**On*Event);
}
常规混淆配置好,可以增加你项目中的混淆了,如数据模型bean,第三方sdk等.混淆也可以写个接口类,然让不混淆的类实现此接口比较简便,在gradle总直接配置不混淆的base即可。
代码语言:javascript复制 -keep class com.baidu.pushsdk.** { *;}
-keep class com.mybisniss.mybean.** { *;}
总结
以上是是通常的gradle打包过程中遇到的注意事项,大致能满足初学者对as的需求。
推荐
Gradle敏捷打包,多版本,多渠道,多环境,多功能,多模块随心所欲
开发者技术前线
END