前面我们已经介绍了使用蓝贝壳儿打包,但是那只能使用eclipse来进行,因为好像没有发现android studio有那个插件,以前也介绍了打jar(gradlew makeJar),这里介绍使用AS利用gradlew多渠道打包(APK):
在做地图或者一些需要正式打包的第三方功能的时候,打包调试修改在打包在调试在修改…,相信有不少小伙伴经历过这个苦不堪言的过程,那么只能说你对gradle还不了解,signingConfigs就可以很好的解决这个问题.
步骤如下
1.配置签名信息
点击OK后会在module的build.gradle目录下生成对应代码
2.配置buildType中签名
点击OK后会在module的build.gradle目录下生成对应代码
这个时候你在Run App就已经是正式签名的了 当然如果很熟悉gradle的语法上面的过程你也可以直接手写
但是到此是不是感觉有点不妥..因为签名的信息在build.gradle中是明文展示的.虽然不会打包到apk当中,但是会提交到代码仓库那么公司其他人就可以看到.所以为了安全我们新建一个signing.properties文件在module目录下然后将keyStore信息写在该文件中并且不提交到代码仓库.这样别人就无法看到了.
signing.properties配置如下
STORE_FILE=test.jks
STORE_PASSWORD=123456
KEY_ALIAS=test
KEY_PASSWORD=123456
这里需要注意下signing.properties中STORE_FILE签名文件的相对路径是相对app目录开始的即在这里是
C:\Users\MSI\Desktop\BaseDemo\app
在修改下signingConfigs中关于签名配置的部分先上效果图
在贴上代码方便复制
File propFile = file('signing.properties');
if (propFile.exists()) {
def Properties props = new Properties()
props.load(new FileInputStream(propFile))
if (props.containsKey('STORE_FILE') && props.containsKey('STORE_PASSWORD') &&
props.containsKey('KEY_ALIAS') && props.containsKey('KEY_PASSWORD')) {
storeFile = file(props['STORE_FILE'])
storePassword = props['STORE_PASSWORD']
keyAlias = props['KEY_ALIAS']
keyPassword = props['KEY_PASSWORD']
}
}
as手动添加渠道
然后我们去看Modul的gradle文件:
productFlavors { meizu { minSdkVersion 21 proguardFile 'E:/AndroidStudioProjects/RevealLayout/app/proguard-rules.pro' targetSdkVersion 23 versionName '1.0' } }显然我们不太喜欢去手动添加,因为感觉还是相对的麻烦。
所以我们可以直接在gradle脚本里操作:
productFlavors { dev { manifestPlaceholders = [channel: "dev"] } xiaomi { manifestPlaceholders = [channel: "xiaomi"] } wandoujia { manifestPlaceholders = [channel: "wandoujia"] } "360" { manifestPlaceholders = [channel: "360"] } }这样我们就轻松的配置了4个渠道信息,是不是感觉比那个还是简单点。。
接着我们去同步(asyn now)一次,发现Build Variant会多了很多渠道是不是
渠道配置好了,接下来我们就是来打包了
直接在终端:gradlew build
等所有的apk都打完我使用了 2 mins 28.212 secs,感觉机子还是相当的渣。
这样就会把所有的包打好,每种渠道的debug和release版本都会打包。当然这些都是没有签名文件的,我这里是演示一下gradlew build命令而已。
没有签名文件的就需要生成签名文件
(不会去百度,我艹),有签名文件的那就好办了,直接来配置build.gradle
buildTypes { debug { manifestPlaceholders = [app_label:"@string/app_name_debug"] } release { manifestPlaceholders = [app_label:"@string/app_name"] } preview{ manifestPlaceholders = [app_label:"@string/app_name_preview"] } }签名信息的配置
signingConfigs { debug { storeFile file("C:/Users/test1/Desktop/android.jks") storePassword "xxxxxx" keyAlias "xxxxx" keyPassword "xxxxxx" } preview { storeFile file("C:/Users/test1/Desktop/android.jks") storePassword "xxxxxx" keyAlias "xxxxxx" keyPassword "xxxxx" } release { storeFile file("C:/Users/test1/Desktop/android.jks") storePassword "xxxxxx" keyAlias "xxxxxx" keyPassword "xxxxxx" } }接下来我们就来根据配置的渠道,来输出目录:
applicationVariants.all { variant -> variant.outputs.each { output -> output.outputFile = new File( output.outputFile.parent, "RevealLayout-${variant.buildType.name}-${variant.versionName}-${variant.productFlavors[0].name}.apk".toLowerCase()) } }接下来就是看图,新生成的apk文件:
是不是生成了签名的apk文件了,不扯了,我也是醉了。
上面那种打包方式也是坑:(生成apk)
敲下gradle assembleRelease指令就可以去喝咖啡了(记得配置gradle环境变量)
该命令是生成不同Product Flavor即不同渠道的release版本
除此之外 assemble 还能和 Product Flavor 结合创建新的任务,其实 assemble 是和 Build Variants 一起结合使用的,而 Build Variants = Build Type + Product Flavor , 举个例子大家就明白了:
如果我们想打包wandoujia渠道的release版本,执行如下命令就好了:
gradle assembleWandoujiaRelease
如果我们只打wandoujia渠道版本,则:
gradle assembleWandoujia
此命令会生成wandoujia渠道的Release和Debug版本
同理我想打全部Release版本:
gradle assembleRelease
这条命令会把Product Flavor下的所有渠道的Release版本都打出来。
总之,assemble 命令创建task有如下用法:
assemble: 允许直接构建一个Variant版本,例如assembleFlavor1Debug。
assemble: 允许构建指定Build Type的所有APK,例如assembleDebug将会构建Flavor1Debug和Flavor2Debug两个Variant版本。
assemble: 允许构建指定flavor的所有APK,例如assembleFlavor1将会构建Flavor1Debug和Flavor1Release两个Variant版本。
当然还是建议直接手点不容易出错
生成的apk在module\build\outputs目录下
4.验证
验证代码如下
private String getApplicationMetaValue(String name) {
String value= "";
try {
ApplicationInfo appInfo =getPackageManager()
.getApplicationInfo(getPackageName(),
PackageManager.GET_META_DATA);
value = appInfo.metaData.getString(name);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return value;
}
通过该代码就可以获取到渠道名并打印出来,这里就不演示了
配置了多渠道打包后为了方便区分apk版本等等信息…我们在配置下生成APK的名字,只需在module/build.gradle文件下添加如下配置
def packageTime() {
return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
android {
//........
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
File outputDirectory = new File(outputFile.parent);
def fileName
if (variant.buildType.name == "release") {
fileName = "app_v${defaultConfig.versionName}_${packageTime()}_${variant.productFlavors[0].name}_release.apk"
} else if(variant.buildType.name == "debug") {
fileName = "app_v${defaultConfig.versionName}_${packageTime()}_${variant.productFlavors[0].name}_beta.apk"
}
output.outputFile = new File(outputDirectory, fileName)
}
}
}
}
细心的小伙伴应该发现在 app/build/outputs/apk 文件夹中,可以看到一些文件名末尾带有 unaligned 文字的冗余文件,这些文件没有用,可以删掉,只需要在上面的基础上在build.gradle 中添加下列命令就好了
applicationVariants.all { variant ->
variant.outputs.each { output ->
def outputFile = output.outputFile
if (outputFile != null && outputFile.name.endsWith('.apk')) {
File outputDirectory = new File(outputFile.parent);
def fileName
if (variant.buildType.name == "release") {
fileName = "app_v${defaultConfig.versionName}_${packageTime()}_${variant.productFlavors[0].name}_release.apk"
} else if(variant.buildType.name == "debug") {
fileName = "app_v${defaultConfig.versionName}_${packageTime()}_${variant.productFlavors[0].name}_beta.apk"
}
output.outputFile = new File(outputDirectory, fileName)
}
// 删除unaligned apk
if (output.zipAlign != null) {
output.zipAlign.doLast {
output.zipAlign.inputFile.delete()
}
}
}
}
我靠,AS多渠道打包就搞完了,不解释,你要学习
./gradlew clean 删除HelloWord/app目录下的build文件夹
./gradlew build 检查依赖并编译打包
这里注意的是./gradlewbuild命令把debug、release环境的包都打出来,生成的包在目录XXX/app/build/outputs/apk/下。如果正式发布只需要打release的包,该怎么办呢,下面介绍一个很有用的命令 assemble, 如
./gradlew assembleDebug 编译并打Debug包
./gradlew assemblexiaomiDebug 编译并打xiaomi的debug包,其他类似
./gradlew assembleRelease 编译并打Release的包
./gradlew assemblexiaomiRelease 编译并打xiaomi的Release包,其他类似
./gradlew installRelease Release模式打包并安装
./gradlew uninstallRelease 卸载Release模式包
1 gradlew build 和 gradle build 有区别吗?
使用gradle wrapper是gradle官方推荐的build方式,而gradlew正是运行了wrapper task之后生成的(运行wrapper task是Android Studio自动做的)。使用gralde wrapper的一个好处就是每个项目可以依赖不同版本的gradle,构建的时候gradle wrapper会帮你自动下载所依赖的版本的gradle。而如果你使用gradle build的话,同时你又有多个项目使用不同版本的gradle,那就需要你手动在自己的机器上配置多个版本的gradle,稍微麻烦一些
本文参考http://www.jayfeng.com/2015/11/07/Android%E6%89%93%E5%8C%85%E7%9A%84%E9%82%A3%E4%BA%9B%E4%BA%8B/
哈哈哈,里面还包含了AS下的代码混淆等。