AndroidStudio3.2的多渠道自动化打包问题

文章目录

    • 多渠道打包的配置
    • android studio多渠道打包错误
    • 完整的build.gralde文件
      • 自定义config.gardle样例格式
      • 配置多渠道信息的module下的build.gardle

多渠道打包的配置

网上有很多利用第三方框架进行打包的平台,例如友盟,美团的瓦力等等,这些框架确实功能强大,但是对于自己的项目,如果只是为了打个多渠道包就去引入一个第三方框架,实在难登大雅,下边就介绍一下我们利用Gradle在AndroidStudio中配置多渠道打包的操作,这里指定了as版本是因为笔者目前使用的AndroidStudio是3.2的版本,目前的最新版遇到有个别问题(在低版本上不知是否依然存在),故有此说。

//    flavorDimensions "versionCode" // flavor dimension 它的维度就是该版本号,统一维度,
    productFlavors {
//       一下括号中的  dimension "versionCode"可以删除
        Alia {

        }
        Xiaomi {

        }
        Huawei {

        }
        Vivo {

        }
        Oppo {

        }
        Tencent {
//            dimension "versionCode"
        }

    }

    productFlavors.all { flavor ->
        flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: flavor.name]
    }

上文的 flavorDimensions “versionCode” 也可以写在defaultconfig中,做统一纬度配置

 defaultConfig {
        applicationId appConfig.appId
        minSdkVersion versions.minSdkVersion
        targetSdkVersion versions.targetSdkVersion
        versionCode versions.versionCode
        versionName versions.versionName
        flavorDimensions "versionCode" // flavor dimension 它的维度就是该版本号,统一维度,
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

android studio多渠道打包错误

如果在多渠道配置的时候没有指定统一的纬度,也就是没有flavorDimensions 属性,就会有以下错误

AAPT2 的错误,要先在自己代码中找问题,不要看见他就是false,已经不好使了。

  1. 如果在多渠道配置的时候没有指定统一的纬度,也就是没有flavorDimensions 属性,就会有以下错误
 Daemon: AAPT2 aapt2-3.2.1-4818971-windows Daemon #0

此时千万不要把aapt2设置false来解决,现在这个方法已经过时被弃用了,所以在新版AndroidStudio3.2中多渠道打包配置是必须要指定统一纬度的,由此也可见,看到了

  1. Error:error: failed to read PNG signature: file does not start with PNG signature

这个就是你的资源文件有问题,可能是某一个png图片解析失败了,你可以编辑这张图片另存一下再使用,或者将png的图片修改一下后缀格式,例如改成jpg格式。此问题可解。

完整的build.gralde文件

里边隐藏了项目签名文件和配置信息,还有第三方的appkey,APPID等重要信息。为了安全考虑,都写在了一个自定义的.gradle文件中,这个自定义文件在版本控制的时候是不用上传的,这样就有效保护了项目的安全,就算别人拿到了你的源码,没有这些东西,他什么也干不了

自定义config.gardle样例格式

ext.versions = [
        // 本地仓库版本
        compileSdkVersion: 26,
        buildToolsVersion: "26.0.3",
        minSdkVersion    : 18,
        targetSdkVersion : 26,
        versionCode      : 4,
        versionName      : "1.2.1",
        supportVersion   : "25.3.0",
        loggerVersion      : "2.2.0"
]

// app 相关信息总配置
ext.appConfig = [
        appId            : 'dingshi.com.hibook',
        betaName         : '@string/app_name',
        proName          : '@string/app_name',
//        keyAlias     : 'hibook',
//        keyPassword  : 'hibook',
//        storeFile    : 'hibook.jks',
//        storePassword: 'hibook',
        GETUI_APP_ID     : "PhmRY1Uy8A9VrK2L2H8Qz3",
        GETUI_APP_KEY    : "VXJjCzXD0M7UqsPzFbXtT7",
        GETUI_APP_SECRET : "ZmO60vhutt6NxMauNZJjl8",
//      EASEMOB_DEBUG    : "1191180110115352#hello-book-dev",
        EASEMOB_DEBUG    : "1191180110115352#hello-book",
        EASEMOB_RELEASE  : "1191180110115352#hello-book",
        LOCALHOST_DEBUG  : "\"http://api.linkbooker.com/\"",
//      LOCALHOST_DEBUG  : "\"http://testapi.linkbooker.com/\"",
        LOCALHOST_RELEASE: "\"http://api.linkbooker.com/\""

]

ext.channel = [
        HIBOOK_TEST_NAME: "test_channel",
        Baidu           : "Baidu",
        Xiaomi          : "Xiaomi",
        Huawei          : "huawei",
        Vivo            : "vivo",
        Oppo            : "oppo",
        Tencent         : "tencent",
        Server          : "server"
]

配置多渠道信息的module下的build.gardle

apply plugin: 'com.android.application'
apply from: "$rootDir/config.gradle"

android {
    signingConfigs {
        config {
            keyAlias appConfig.keyAlias
            keyPassword appConfig.keyPassword
            storeFile file(appConfig.storeFile)
            storePassword appConfig.storePassword
        }
    }
    compileSdkVersion versions.compileSdkVersion
    defaultConfig {
        applicationId appConfig.appId
        minSdkVersion versions.minSdkVersion
        targetSdkVersion versions.targetSdkVersion
        versionCode versions.versionCode
        versionName versions.versionName
        flavorDimensions "versionCode" // flavor dimension 它的维度就是该版本号,统一维度,
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            buildConfigField "String", "LOCALHOST", appConfig.LOCALHOST_RELEASE
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            debuggable true
            jniDebuggable true
            renderscriptDebuggable true
            zipAlignEnabled true
        }
        debug {
            buildConfigField "String", "LOCALHOST", appConfig.LOCALHOST_DEBUG
            debuggable true
            jniDebuggable true
            signingConfig signingConfigs.config
            renderscriptDebuggable true
            minifyEnabled true
            pseudoLocalesEnabled true
            zipAlignEnabled true
        }
    }
    buildToolsVersion versions.buildToolsVersion
//    dexOptions {
//        incremental true
//    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

//    flavorDimensions "versionCode" // flavor dimension 它的维度就是该版本号,统一维度,
    productFlavors {
//       一下括号中的  dimension "versionCode"可以删除
        Alia {

        }
        Xiaomi {

        }
        Huawei {

        }
        Vivo {

        }
        Oppo {

        }
        Tencent {
//            dimension "versionCode"
        }

    }

    productFlavors.all { flavor ->
        flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: flavor.name]
    }



    //***AS3.0版本 设置apk名称***
    android.applicationVariants.all { variant ->
        variant.outputs.all {
            if (variant.name.endsWith("Debug")) {
                //debug包
                outputFileName = "$applicationId _v${defaultConfig.versionName}_${getDate()}_code${defaultConfig.versionCode}_debug.apk"
            } else {
                //release包
                variant.outputs.each { output ->
                    def appName = 'athesismentor'
                    def oldFile = output.outputFile
                    def buildName
                    def releaseApkName

                    variant.productFlavors.each { product ->
                        buildName = product.name
                    }

                    releaseApkName = appName + '-' + buildName + '-' + getDate() + '_release.apk'
//                output.outputFile = new File(oldFile.parent, releaseApkName)
                    outputFileName =releaseApkName
//                  outputFileName = "$applicationId _v${defaultConfig.versionName}_code${defaultConfig.versionCode}_${getDate()}_release.apk"
                }

            }
        }
    }
}
//获取时间戳
static def getDate() {
    def date = new Date()
    def formattedDate = date.format('yyyy-MM-dd-HH_mm')
    return formattedDate
}


configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        def requested = details.requested
        if (requested.group == 'com.android.support') {
            if (!requested.name.startsWith("multidex")) {
                details.useVersion versions.supportVersion
            }
        }
    }
}
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    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.orhanobut:logger:$versions.utilVersion"
}

##Gradle3.0以上(3.3)版本生成自动化apk名称有用如下方法替换

上述生成自定义apk的方法是写在android{}节点下的,以下方法要写在android{ buildType{生成自定义apk名称 } }节点下,如下:

android.applicationVariants.all { variant ->
    variant.outputs.each { output ->
        def outputFile = output.outputFile
        if (outputFile != null && outputFile.name.endsWith('.apk')) {
            def fileName = outputFile.name.replace("之前系统默认名称.apk", "想要替换的名称${defaultConfig.versionName}_${getDate()}.apk")
            output.outputFile = new File(outputFile.parent, fileName)
        }
    }
}

当然,上边的getDate方法还是和原来的一样,写在android{}节点以外的根节点下

//获取时间戳
static def getDate() {
    def date = new Date()
    def formattedDate = date.format('MMddHHmm')
    return formattedDate
}

你可能感兴趣的:(Exception,Android)