美文网首页Android进阶之路Android开发Android开发
Android Studio多渠道打包,动态配置appIcon,

Android Studio多渠道打包,动态配置appIcon,

作者: 彼得兔_7454 | 来源:发表于2019-05-17 16:07 被阅读26次

    菜鸟级别的程序媛,首次做多渠道打包,也是查了一些资料,希望可以帮到你们。
    本文来自:https://www.jianshu.com/u/7dcee8463e30


    因项目需求,需要给定制客户在原有基础上出一个APP,只更换APP的icon和name。同时项目也有少量部分需要修改的地方,为了更好的迭代开发,Gradle的多渠道打包就派上用场了。


    先贴一份主Module的build.gradle文件参考

    apply plugin: 'com.android.application'
    
    //************************新增***************************
    //获取当前的时间
    def releaseTime() {
        return new Date().format("HHmm")
    }
    //设置自增长版本号
    def getVersionCode() {
        def versionFile = file('version.properties')// 读取第一步新建的文件
        if (versionFile.canRead()) {// 判断文件读取异常
            Properties versionProps = new Properties()
            versionProps.load(new FileInputStream(versionFile))
            def versionCode = versionProps['VERSION_CODE'].toInteger()// 读取文件里面的版本号
            def runTasks = gradle.startParameter.taskNames
            if ('assembleRelease' in runTasks) {//仅在assembleRelease任务是增加版本号,其他渠道包在此分别配置
                // 版本号自增之后再写入文件(此处是关键,版本号自增+1)
                versionProps['VERSION_CODE'] = (++versionCode).toString()
                versionProps.store(versionFile.newWriter(), null)
            }
            return versionCode // 返回自增之后的版本号
        } else {
            throw new GradleException("Could not find version.properties!")
        }
    }
    
    def getVersionName() {
        def date = new Date()
        def versionName = date.format('yyyyMMdd')
        return versionName
    }
    
    def currentVersionCode = getVersionCode()
    def currentVsionName = getVersionName()
    android {
        compileSdkVersion rootProject.ext.compileSdkVersion
        buildToolsVersion rootProject.ext.buildToolsVersion
        // 取消掉系统对.9图片的检查
        aaptOptions.cruncherEnabled = false
        aaptOptions.useNewCruncher = false
        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
        }
    //需要添加下面选项,否则无法run app
        dexOptions {
            javaMaxHeapSize "4g"
    //        incremental true
            jumboMode = true
            preDexLibraries = false
        }
        defaultConfig {
            applicationId "com.andorid.xxx.xxx"
            minSdkVersion rootProject.ext.minSdkVersion
            targetSdkVersion rootProject.ext.targetSdkVersion
            versionCode currentVersionCode
            versionName currentVsionName
            multiDexEnabled true
            flavorDimensions "app"//新增
            javaCompileOptions { annotationProcessorOptions { includeCompileClasspath = true } }
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "Umeng"]
            ndk {
                //设置支持的SO库架构
                abiFilters "armeabi", "armeabi-v7a", "x86"
            }
            vectorDrawables.useSupportLibrary = true
            javaCompileOptions {
                annotationProcessorOptions {
                    includeCompileClasspath = true
                }
            }
    
        }
        buildTypes {
            debug {
                minifyEnabled false
                zipAlignEnabled false
                shrinkResources false
                debuggable true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    
            }
            release {
                minifyEnabled true
                zipAlignEnabled false
                shrinkResources false
                debuggable false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
        //*************************新增start**********************************
        productFlavors {
            //********(默认渠道)******
            pro {
                manifestPlaceholders = [
                        UMENG_CHANNEL_VALUE: "pro",
                        app_icon           : "@drawable/pro_icon",
                        app_name           : "@string/pro_app_name",
                ]
            }
    
            //********定制的XXX(applicationId不一样)******
            dev {
                applicationId "com.andorid.xxx.xxx"
                manifestPlaceholders = [
                        UMENG_CHANNEL_VALUE: "dev",
                        app_icon           : "@drawable/dev_logo",
                        app_name           : "@string/dev_app_name",
                ]
            }
        }
        android.applicationVariants.all {
            variant ->
                variant.outputs.all {
                    output ->
                        def outputFile = output.outputFile
                        def fileName
                        if (outputFile != null && outputFile.name.endsWith('.apk')) {
                            if (variant.buildType.name.equals('release')) {
                                fileName = "${variant.productFlavors[0].name}_release_${defaultConfig.versionName}_${releaseTime()}.apk"
                            } else if (variant.buildType.name.equals('debug')) {
                                fileName = "${variant.productFlavors[0].name}_debug_${defaultConfig.versionName}_${releaseTime()}.apk"
                            }
                            outputFileName = fileName
                        }
                }
        }
    //*************************新增End**********************************
    
    
        sourceSets {
            main {
                jniLibs.srcDirs = ['src/main/jniLibs']
            }
        }
        //引人aar
        repositories {
            flatDir {
                dirs 'libs'
            }
            maven { url "https://jitpack.io" }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
    
        dataBinding {
            enabled = true
        }
    
        dependencies {
            compileOnly fileTree(dir: 'libs', include: ['*.jar'])
            implementation 'com.android.support:appcompat-v7:28.0.0'
            implementation 'com.android.support.constraint:constraint-layout:1.1.3'
            implementation 'com.android.support:design:28.0.0'
            testImplementation 'junit:junit:4.12'
            androidTestImplementation 'com.android.support.test:runner:1.0.2'
            androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    
    
            implementation 'com.google.code.gson:gson:2.8.2'
            implementation files('libs/glide-3.7.0.jar')
            implementation files('libs/jaxen-1.1.1.jar')
            implementation 'org.greenrobot:eventbus:3.0.0'
            compile 'com.orhanobut:logger:2.1.1'
            compile 'com.zhy:okhttputils:2.6.2'
            compile 'com.android.support:multidex:1.0.1'
            compile 'com.squareup.okhttp3:okhttp:3.3.0'
            compile 'com.umeng.sdk:debug:1.0.0'
            implementation 'me.jessyan:autosize:1.1.2'
        }
    }
    
    

    下面请跟着我的步骤来

    由于andorid对每个app唯一标识是用applicationId来标识的,所以每个渠道的包根据applicationId来区分。

     productFlavors {
            //********(默认渠道)******
            pro {
                manifestPlaceholders = [
                        UMENG_CHANNEL_VALUE: "pro",
                        app_icon           : "@drawable/pro_icon",
                        app_name           : "@string/pro_app_name",
                ]
            }
    
            //********定制的xxx(applicationId不一样)******
            dev {
                applicationId "com.android.xxx.xxx"
                manifestPlaceholders = [
                        UMENG_CHANNEL_VALUE: "dev",
                        app_icon           : "@drawable/dev_logo",
                        app_name           : "@string/dev_app_name",
                ]
            }
        }
    

    记得在AndroidManifest文件的application节点中引用app的icon和name
    meta-data节点一定不能少的哦别忘记了。这里的配置是动态改变icon和name

    <application···
     android:icon="${app_icon}"
     android:label="${app_name}"
      
      <meta-data
                android:name="CHANNEL_ID"
                android:value="${UMENG_CHANNEL_VALUE}" />
    

    接下就是打包app里,我这里做了一个判断,给apk包名命名是debug的还是release的

       android.applicationVariants.all {
            variant ->
                variant.outputs.all {
                    output ->
                        def outputFile = output.outputFile
                        def fileName
                        if (outputFile != null && outputFile.name.endsWith('.apk')) {
                            if (variant.buildType.name.equals('release')) {
                                fileName = "${variant.productFlavors[0].name}_release_${defaultConfig.versionName}_${releaseTime()}.apk"
                            } else if (variant.buildType.name.equals('debug')) {
                                fileName = "${variant.productFlavors[0].name}_debug_${defaultConfig.versionName}_${releaseTime()}.apk"
                            }
                            outputFileName = fileName
                        }
                }
        }
    

    接下来就让我们来看一下打包的效果吧!


    image.png

    另外如果程序里面某些配置需要根据不同的渠道配置,可以获取applicationId,也就是包名。

    例如: image.png

    好了多渠道打包,并动态改变icon和name的方法就这么简单。希望可以帮到你们!

    相关文章

      网友评论

        本文标题:Android Studio多渠道打包,动态配置appIcon,

        本文链接:https://www.haomeiwen.com/subject/tcyoaqtx.html