Android(安卓)使用 Gradle 多渠道打包
16lz
2022-07-02
安卓开发完成,对于一个开放应用而言,我们需要发布到不同的应用市场,同时我们也需要统计不同市场的用户下载量。(通过启动应用后获取不同市场apk中的不同值来区分)
下面用一个具体的实例来说明:
1、在AndroidManifest.xml的application内添加meta-data标签
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name"> <meta-data android:name="APP_CHANNEL" android:value="${APP_CHANNEL_VALUE}" /> <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity></application>
2、修改build.gradle文件,在android {} 中添加
android { // 打包渠道List productFlavors { wandoujia { manifestPlaceholders = [APP_CHANNEL_VALUE: "豌豆荚"] } cn360 { manifestPlaceholders = [APP_CHANNEL_VALUE: "360"] } baidu { manifestPlaceholders = [APP_CHANNEL_VALUE: "百度"] } tencent { manifestPlaceholders = [APP_CHANNEL_VALUE: "应用宝"] } sougou { manifestPlaceholders = [APP_CHANNEL_VALUE: "搜狗市场"] } }}
或者使用下面方法,直接使用flavor的name做为${APP_CHANNEL_VALUE}
android { // 打包渠道List productFlavors { wandoujia {} cn360 {} baidu {} tencent {} sougou {} } // 批量处理,直接使用flavor的name作为APP_CHANNEL_VALUE的值 productFlavors.all { flavor -> flavor.manifestPlaceholders = [APP_CHANNEL_VALUE: name] } }
这样就完成了,执行 gradle assembleRelease 喝口茶坐等便可。
完成后,到build/outputs/apk中就可以看到各种渠道包。
有关assemble可用的命令还有:
gradle assembleDebug //所有Debug版本gradle assembleRelease //所有Release版本gradle assembleBaidu //指定渠道的Debug和Release版本gradle assembleBaiduDebug //指定渠道的Debug版本gradle assembleBaiduRelease //指定渠道的Release版本gradle build //所有渠道的Debug和Release版本
最后附上我的 MainActivity 和 build.gradle
package com.example.myandroid;import android.app.Activity;import android.content.pm.ApplicationInfo;import android.content.pm.PackageManager;import android.content.pm.PackageManager.NameNotFoundException;import android.os.Bundle;import android.widget.Toast;/** * 应用入口 * * @author SHANHY(365384722@QQ.COM) * @date 2015年12月30日 */public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String channel = getAppMetaData("APP_CHANNEL"); if(channel != null) Toast.makeText(this, channel, Toast.LENGTH_SHORT).show(); } /** * 获取Application下面的metaData * * @param name * @return * @author SHANHY * @date 2015年12月30日 */ public String getAppMetaData(String meta_name){ try { ApplicationInfo appInfo = this.getPackageManager() .getApplicationInfo(getPackageName(),PackageManager.GET_META_DATA); return appInfo.metaData.getString(meta_name); } catch (NameNotFoundException e) { e.printStackTrace(); } return null; }}
完整的 build.gradle 脚本
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.0.0-alpha3' }}apply plugin: 'com.android.application'dependencies { compile fileTree(dir: 'libs', include: '*.jar')}android { compileSdkVersion 14 buildToolsVersion "23.0.2" defaultConfig { // 可以手动修改如下一些配置,无需改动任何代码便可以生成对应配置的apk applicationId "com.example.myandroid.aaa" minSdkVersion 8 targetSdkVersion 21 versionCode 200 versionName "2.0.0" // dex突破65535限制 multiDexEnabled true // 默认打包渠道(官方) manifestPlaceholders = [APP_CHANNEL_VALUE: "官方"] } // 打包渠道List productFlavors { myself { manifestPlaceholders = [APP_CHANNEL_VALUE: "官方"] } wandoujia { manifestPlaceholders = [APP_CHANNEL_VALUE: "豌豆荚"] } cn360 { manifestPlaceholders = [APP_CHANNEL_VALUE: "360"] } baidu { manifestPlaceholders = [APP_CHANNEL_VALUE: "百度"] } tencent { manifestPlaceholders = [APP_CHANNEL_VALUE: "应用宝"] } sougou { manifestPlaceholders = [APP_CHANNEL_VALUE: "搜狗市场"] } } // 打包渠道List //productFlavors { // myself {} // wandoujia {} // cn360 {} // baidu {} // tencent {} // sougou {} //} // 批量处理,直接使用flavor的name作为APP_CHANNEL_VALUE的值(也可以不使用该方法,在productFlavors中逐一配置) //productFlavors.all { flavor -> // flavor.manifestPlaceholders = [APP_CHANNEL_VALUE: name] //} lintOptions { abortOnError false } sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } // 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') } //签名信息 signingConfigs { debug{ // No Debug Config } release { storeFile file("xxxxx.key") storePassword "xxxxx" keyAlias "xxxxx" keyPassword "xxxxx" } } buildTypes { //Debug模式 debug { // 显示LOG,在java代码中的调用方式为:BuildConfig.LOG_DEBUG,AS工具可以在BuildConfig.java中新增这个字段,如果还要兼容使用eclipse,不建议使用新增字段,因为eclipse在clean后会重新生成BuildConfig.java(默认使用BuildConfig.DEBUG能满足需要就不要特殊处理了) //buildConfigField "boolean", "LOG_DEBUG", "true" versionNameSuffix "-debug" // 不开启混淆 minifyEnabled false // 不需要ZIP优化 zipAlignEnabled false // 不需要资源压缩 shrinkResources false // signingConfig signingConfig signingConfigs.debug } //Release模式 release { // 不显示LOG //buildConfigField "boolean", "LOG_DEBUG", "true" minifyEnabled true zipAlignEnabled true // 资源压缩,移除无用的资源文件 shrinkResources true // 混淆文件配置 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' // 签名信息配置(如果上面配置了defaultConfig则可以不用指定signingConfig) signingConfig signingConfigs.release applicationVariants.all { variant -> variant.outputs.each { output -> def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith('.apk')) { // 输出apk名称为myandroid_v1.0.0_2015-12-30_baidu.apk def fileName = "myandroid_v${defaultConfig.versionName}_${releaseTime()}_${variant.productFlavors[0].name}.apk" output.outputFile = new File(outputFile.parent, fileName) } } } } }} // 声明一个方法,获取打包时间def releaseTime() { return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))}
更多相关文章
- 箭头函数的基础使用
- NPM 和webpack 的基础使用
- Python list sort方法的具体使用
- 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
- android 使用html5作布局文件: webview跟javascript交互
- Android(安卓)Resource介绍和使用
- "Failed to fetch URL https://dl-ssl.google.com/android/repos
- 使用NetBeans搭建Android开发环境
- Android(安卓)studio3.x 多渠道打包apk