gradle构建多渠道包(多applicationId,多图标,多app名称)

news/2024/5/20 2:51:34 标签: gradle, 多渠道, 多icon, 多包名

如何利用同一套代码,要打包不同applicationId,不同图标,不同包名,不同启动页等?此时就需要用到构建神器-gradle
先上代码

...
def releaseTime() {
    return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}

android {
    compileSdkVersion 25
    buildToolsVersion '25.0.2'

    defaultConfig {
        applicationId "com.edt.edtdoctor"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 124
        versionName "1.2.4"

        ndk {
            abiFilters "armeabi"/*, "x86"*/
        }
        buildConfigField("String", "CHAT_DIRECTION", '"1"')
        buildConfigField("String", "XF_APPID", '"***"')
        buildConfigField("String", "CLIENT_ID", '"doctor"')
        buildConfigField("String", "WECHAT_KEY_VALUE", '"***"')
        //Enabling multidex support
        multiDexEnabled true
    }

    tasks.whenTaskAdded { task ->
        if (task.name.contains("lint")
                //如果instant run不生效,把clean这行干掉
                //||task.name.equals("clean")
                //如果项目中有用到aidl则不可以舍弃这个任务
                ||task.name.contains("Aidl")
                //用不到测试的时候就可以先关闭
                ||task.name.contains("mockableAndroidJar")
                ||task.name.contains("UnitTest")
                ||task.name.contains("AndroidTest")
                //用不到NDK和JNI的也关闭掉
                //|| task.name.contains("Ndk")
                //|| task.name.contains("Jni")
        ) {
            task.enabled = false
        }
    }

    signingConfigs {
        release {
            try {
                storeFile file('./keystore/edt_edtdoctor.jks')
                keyAlias 'china'
                keyPassword '******'
                storePassword '******'
            } catch (ex) {
                throw new InvalidUserDataException(ex.toString())
            }

        }
        debug {
            storeFile file("./keystore/debug.keystore")
        }
    }
    //友盟统计不同渠道(具体值看androidManifest.xml)
    productFlavors {

        huawei {
            applicationId "com.edt.***"
            buildConfigField("boolean", "IS_DEVELOP", "false")
            resValue "string", "app_name", "appName"
            buildConfigField("String", "BUGLY_ID", '"***"')
            manifestPlaceholders = [JPUSH_APPKEY_VALUE  : "***",
                                    EASEMOB_APPKEY_VALUE: "***",
                                    UMENG_APPKEY_VALUE  : "***",
                                    UMENG_CHANNEL_VALUE : "huawei",
                                    START_BACKGROUND    : "@style/Splash_Theme",
                                    app_icon            : "@mipmap/ic_launcher"]
        }
        develop {
            applicationId "com.edt.***"
            buildConfigField("boolean", "IS_DEVELOP", "true")
            resValue "string", "app_name", "another"
            buildConfigField("String", "BUGLY_ID", '"***"')
            manifestPlaceholders = [JPUSH_APPKEY_VALUE  : "***",
                                    EASEMOB_APPKEY_VALUE: "***",
                                    UMENG_APPKEY_VALUE  : "***",
                                    UMENG_CHANNEL_VALUE : "develop",
                                    START_BACKGROUND    : "@style/Three_Splash_Theme",
                                    app_icon            : "@drawable/icon"]
        }

//        productFlavors.all { flavor ->
//            //UMENG_CHANNEL_VALUE即为AndroidManifest.xml中的具体值,此值代表统计渠道
//            flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
//        }

    }


    lintOptions {
        tasks.lint.enabled = false
        checkReleaseBuilds false
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false

    }

    configurations.all {
        resolutionStrategy.force 'com.android.support:support-annotations:23.0.1'
    }

    buildTypes {
        debug {
            manifestPlaceholders = [JPUSH_APPKEY_VALUE  : "***",
                                    EASEMOB_APPKEY_VALUE: "***",
                                    UMENG_APPKEY_VALUE: "***",
                                    START_BACKGROUND    : "@style/Splash_Theme",
                                    app_icon: "@mipmap/ic_launcher"]
            buildConfigField("String", "BUGLY_ID", '"***"')
            signingConfig signingConfigs.release
        }

        release {//正式发布的时候使用
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
            // 批量打包
            applicationVariants.all { variant ->
                variant.outputs.each { output ->
                    def outputFile = output.outputFile
                    if (outputFile != null && outputFile.name.endsWith('.apk')) {
                        //输出apk名称为:渠道名_版本名_时间.apk
                        def fileName = "${variant.productFlavors[0].name}_v${defaultConfig.versionName}_${releaseTime()}.apk"
                        output.outputFile = new File(outputFile.parent, fileName)
                    }
                }
            }
        }
    }

    aaptOptions {
        additionalParameters "--no-version-vectors"
    }

    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

}
...

其中需要关注的是三部分:
defaultConfig {},buildTypes {},productFlavors {}
这三部分均可以对applicationId,图标及appname进行设置,但是优先级不同。优先级如下:

buildTypes >  productFlavors > defaultConfig  

设置AndroidManifest.xml中的属性可以通过manifestPlaceholders 进行设置,不同场景下的常量可以通过buildConfigField进行设置,资源的引用通过resValue 进行设置。

一、设置不同的app图标:

1、在AndroidManifest.xml中
将icon的属性值修改为”${app_icon}”

 <application
        android:name=".core.global.UserApplication"
        android:allowBackup="true"
        android:icon="${app_icon}"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

    ......

 </application>

2、在app.gradle文件下对”${app_icon}”中的app_icon的值进行设置。如下

manifestPlaceholders = [app_icon: "@mipmap/ic_launcher"]

注意:如果是通用的属性,可以在defaultConfig 中进行设置;不同的属性,通过productFlavors 或者buildTypes (设置debug或者release)进行设置。
3、如果编译是报错,可以加上如下语句:

 lintOptions {
        checkReleaseBuilds false
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false

    }

二、设置不同app名称

1、注释掉strings.xml中的app_name的资源

<resources>
    <!--<string name="app_name">心伴医生</string>-->
    <string name="ToastError">网络错误,请检查网络后重试</string>
    <string name="sava_success">保存成功</string>
</resources>

2、在app.gradle文件下设置app_name的资源

resValue "string", "app_name", "app名称"

三、修改不同的applicationId

1、在AndroidManifest.xml中修改包名为${applicationId}引用,如下

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.edt.edtdoctor">
    <permission
        android:name="${applicationId}.permission.JPUSH_MESSAGE"
        android:protectionLevel="signature"/>
    <uses-permission android:name="${applicationId}.permission.JPUSH_MESSAGE"/>
    <application
        android:name=".core.global.UserApplication"
        android:allowBackup="true"
        android:icon="${app_icon}"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".section.entry.controller.activity.StartActivity"
            android:theme="${START_BACKGROUND}">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <meta-data
            android:name="${applicationId}.GlideModule"
            android:value="GlideModule"/>
        <meta-data
            android:name="UMENG_APPKEY"
            android:value="${UMENG_APPKEY_VALUE}"/>
        <meta-data
            android:name="UMENG_CHANNEL"
            android:value="${UMENG_CHANNEL_VALUE}"/>
        <meta-data
            android:name="DOMAIN_PACKAGE_NAME"
            android:value="${applicationId}"/>
        <meta-data
            android:name="EASEMOB_APPKEY"
            android:value="${EASEMOB_APPKEY_VALUE}"/>
        <meta-data
            android:name="JPUSH_CHANNEL"
            android:value="developer-default"/>
        <meta-data
            android:name="JPUSH_APPKEY"
            android:value="${JPUSH_APPKEY_VALUE}"/>
     </application>

2、在app.gradle文件中根据不同的渠道在productFlavors 中进行设置,如下

productFlavors {
        huawei {
            applicationId "com.edt.***"
        }
        develop {
            applicationId "com.edt.***"
        }

四、其他第三方appkey的设置,参考app_icon的设置方式即可。

做完以上设置以后,通过Build > Generate Signed APK,选择签名后,就可以选择不同的渠道进行打包了。如果想要在debug状态下进行测试,将相关的代码复制一份放到buildTypes的debug{}中即可。

注:如果上面有不当的地方,烦请斧正。

参考文章:

Gradle多渠道打包(动态设定App名称,应用图标,替换常量,更改包名,变更渠道)
Android——Gradle 心得 、变量、 多渠道、一些坑
使用Gradle构建多个不同applicationId包


http://www.niftyadmin.cn/n/1723528.html

相关文章

keepalived+mysql主从环境,keepalived返回值是RST,需求解决方法?

环境描述: mysql版本5.6.37 keepalived-1.2.19 系统centos 7&#xff1a;3.10.0-514.26.2.el7 web是&#xff1a;windows server 2012 IIS mysql部署了主从&#xff0c;使用keepalived做高可用&#xff0c;防止数据库故障。web中连接数据库使用了keepalived的VIP地址…

Android水波纹(ripple)点击效果

近日看到某些文章讲水波纹点击效果&#xff0c;使用该效果可以增加用户的体验效果&#xff0c;故看了一下网上文章并做记录。 一、如何使用 1、水波纹效果适用于API21以上&#xff0c;使用的话&#xff0c;需要设置drawable-v21文件夹。 2、具体使用就是在平时使用的drawabl…

云时代架构阅读笔记七——Maven 核心概念与理论

原文链接&#xff1a;https://mp.weixin.qq.com/s/iRufBIJM02eqfr0pwzKMog /artifactId/maven-metadata.xml&#xff0c;将其与本地仓库的对应元数据合并后&#xff0c;计算出RELEASE或者LASTEST的真实值&#xff0c;然后基于真实值检查本地和远程仓库&#xff1b; 如果依赖版本…

RecyclerView设置分割线(自定义宽度与颜色)

RecyclerView自出现后&#xff0c;越来越受到欢迎&#xff0c;源自其强大的扩展性。网上关于RecyclerView用法的文章有很多&#xff0c;我再这里就不再重复搬砖了。在我的使用过程中&#xff0c;就是使用分割线方面还有些生涩&#xff0c;经过网上查阅文章&#xff0c;特做此记…

ViewPager实现懒加载

日常开发中很多场景会用到ViewPagerFragment&#xff0c;一般情况下&#xff0c;我们是通过setOffscreenPageLimit(int limit)方法控制页面的预加载数量。但是有时候&#xff0c;我们又会有这样的需求&#xff0c;当用户滑动到相关页面的时候&#xff0c;才加载相关页面的数据&…

针对屏幕下方出现黑边的手机适配

针对屏幕下方出现黑边的手机适配 最近公司应用安装一款华为手机出现了类似以下的情况&#xff1a; 但是看京东啊&#xff0c;淘宝都是正常的&#xff0c;点击下方“全屏显示”的按钮也能实现不显示下面的黑边&#xff0c;但是这是什么情况呢&#xff1f; 打开华为手机的设置→显…

消息中间件的研究 (三) 协议

AMQP协议 是什么&#xff1f;&#xff1a; AMQP&#xff08; Advanced Message Queuing Protocol&#xff09; 高级消息队列协议使得遵从该规范的客户端应用和消息中间件服务器的全功能互操作成为可能。为什么使用&#xff1f; &#xff1a; 目标是实现一种在全行业广泛使用的…

修改或者替换Toolbar右侧更多按钮(三个点)

问题&#xff1a;项目中需要将一些页面中toolbar的快捷菜单的更多按钮由白色改为黑色&#xff0c;从网上搜过一些&#xff0c;大多是通过修改theme实现&#xff0c;例如Material Design主题与ToolBar讲解&#xff0c;由于需要修改的页面继承的父类是位于framework中&#xff0c…