多渠道打包的两种方式总结

一、友盟多渠道打包

1. 按照友盟官方文档说明,渠道信息通常需要在AndroidManifest.xml中配置如下值:


统计的重点就是value值Channel_ID,即渠道标识,例如:360,qq,wandoujia等等,在这里不直接写出某个渠道名,而是写一个占位符,我们会在build.gradle中进行设置,之后gradle编译的时候会动态的替换掉这个占位符。代码如下:


2. 在app的build.gradle的android{}中添加如下内容:

android {
    flavorDimensions "default"
    productFlavors {
        web {}
        baidu {}
        c360 {}
        qq {}
        wandoujia {}
    }

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

}

也可以单独设置:

android {  
    flavorDimensions "default"
    productFlavors {
        web {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "web "]
        }
        baidu {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "baidu "]
        }
        c360 {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "c360 "]
        }
        qq {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "qq "]
        }
        wandoujia {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
        }
    }  
}

productFlavors是android节点的一个子节点。你需要打什么渠道的包,就在这里按友盟的要求用渠道名给UMENG_CHANNEL_VALUE赋值。上面这个配置的作用就是,为每个渠道包产生不同的 UMENG_CHANNEL_VALUE 的值。

3. 自定义APK名称,多渠道打包

    //自定义APK名称,多渠道打包
    android.applicationVariants.all { variant ->
        variant.outputs.all { output ->
            variant.productFlavors.each { flavor ->
                def project = "cpm"
                def separator = "_"
                def buildType = variant.variantData.variantConfiguration.buildType.name
                def versionName = variant.versionName
                def versionCode = variant.versionCode
                def date = new Date()
                def formattedDate = date.format('yyyyMMdd')

                def apkName = project + separator + "v" + versionName + separator + versionCode + separator + buildType + separator + flavor.name + ".apk"
                if (buildType == "release") {
                    apkName = project + separator + "v" + versionName + separator + versionCode + separator + buildType + separator + flavor.name + separator + formattedDate + ".apk"
                }

                output.outputFileName = apkName
            }
        }
    }

output.outputFileName是apk输出位置,其它的是自定义apk名称,最终输出位置如下图:

image.png

app–>build–>outputs–>apk

4. 配置签名信息,代码如下:

Properties props = new Properties()
props.load(project.rootProject.file('local.properties').newDataInputStream())

android {
    signingConfigs {
            release {
                storeFile file(props['release.keystore'])
                storePassword '123456'
                keyAlias '123456'
                keyPassword '123456'
            }
        }
    }

storeFile file(props[‘release.keystore’])是我的keystore位置,在local.properties中添加如图代码:

image.png

5. 执行打包命令

到这一步,所有配置已经完成,从此以后我们就可以用一行命令打出N个包啦!
我们只需在Android Studio的命令行Terminal下输入以下命令即可:

  • linux下打包全部的Release版渠道包:
./gradlew assembleRelease
  • windows下打包全部的Release版渠道包
gradlew.bat assembleRelease
  • 如果想要Debug的包:
gradlew.bat assembleDebug
  • 如果只要豌豆荚的包:
gradlew.bat assemblewandoujia
  • 如果只要豌豆荚的Release版:
gradlew.bat assemblewandoujiaRelease

6. build.gradle 总的配置文件,供参考:

apply plugin: 'com.android.application'

Properties props = new Properties()
props.load(project.rootProject.file('local.properties').newDataInputStream())

android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    flavorDimensions "default"
    defaultConfig {
        applicationId "com.exmple.myApp"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        multiDexEnabled true
        versionCode 11000
        versionName "1.1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    signingConfigs {
        release {
            storeFile file(props['release.keystore'])
            storePassword '123456'
            keyAlias '123456'
            keyPassword '123456'
        }
    }

    buildTypes {
        debug {
            debuggable true
            minifyEnabled false
            signingConfig signingConfigs.release
        }
        //线上环境
        release {
            debuggable false
            minifyEnabled false
            signingConfig signingConfigs.release
        }
    }

    lintOptions {
        ignoreWarnings true
        checkReleaseBuilds false
    }

    repositories {
        flatDir {
            dirs 'libs'
        }
    }

    sourceSets.main {
        jni.srcDirs = []
        jniLibs.srcDir "src/main/jniLibs"
    }

    productFlavors {
        web {}
        baidu {}
        c360 {}
        qq {}
        oppo {}
        vivo {}
        huawei {}
        mi {}
        meizu {}
        lenovo {}
        leshi {}
        sogou {}
        wandoujia {}
        samsung {}
    }

    productFlavors.all {
        flavor -> flavor.manifestPlaceholders = [CHANNEL_VALUE: name, JPUSH_CHANNEL: name]
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    //自定义APK名称,多渠道打包
    android.applicationVariants.all { variant ->
        variant.outputs.all { output ->
            variant.productFlavors.each { flavor ->
                def project = "cpm"
                def separator = "_"
                def buildType = variant.variantData.variantConfiguration.buildType.name
                def versionName = variant.versionName
                def versionCode = variant.versionCode
                def date = new Date()
                def formattedDate = date.format('yyyyMMdd')

                def apkName = project + separator + "v" + versionName + separator + versionCode + separator + buildType + separator + flavor.name + ".apk"
                if (buildType == "release") {
                    apkName = project + separator + "v" + versionName + separator + versionCode + separator + buildType + separator + flavor.name + separator + formattedDate + ".apk"
                }

                output.outputFileName = apkName
            }
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })

    implementation "com.android.support:appcompat-v7:$supportLibraryVersion"
    implementation "com.android.support:design:$supportLibraryVersion"
    implementation "com.android.support:cardview-v7:$supportLibraryVersion"
    ...
}

二、美团Walle多渠道打包

1.修改项目根目录下build.gradle文件,在buildscripts下的dependencies中增加:

classpath 'com.meituan.android.walle:plugin:1.1.6'

2. 修改app工程的build.gradle文件,增加如下信息:

1)头部增加:

apply plugin: 'walle'

2)确保有签名配置,下面是样例,

signingConfigs {
        release {
            storeFile file("../test.jks")        // 打包的文件的地址
            storePassword "123456"
            keyAlias "test"
            keyPassword "123456"
        }
        debug {
            storeFile file("../test.jks")
            storePassword "123456"
            keyAlias "test"
            keyPassword "123456"
        }
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.debug
        }
    }

3)增加如下配置(按照下面配置生成的渠道包在build/outputs/channels目录下,而不是build/outputs/apk目录):

walle {
    // 指定渠道包的输出路径
    apkOutputFolder = new File("${project.buildDir}/outputs/channels");
    // 定制渠道包的APK的文件名称
    apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
    // 渠道配置文件
    channelFile = new File("${project.getProjectDir()}/channel")
}

4)在dependencies中增加:

implementation 'com.meituan.android.walle:library:1.1.6'

3. 在app工程下新建文件channel,放置渠道信息(根据实际需要修改):

xiaomi
360
huawei
vivo

4. 获取渠道样例:

String channel = WalleChannelReader.getChannel(this.getApplicationContext());

5. 对于要设置到友盟里去,则需要参考友盟的设置方法。

6. 打包命令(更多命令及用法参考附录官方指导):

 mac:./gradlew clean assembleReleaseChannels
 windows:gradlew clean assembleReleaseChannels

7. 生成多渠道包截图:

image.png

8. build.gradle 总的配置文件,供参考:

apply plugin: 'com.android.application'

apply plugin: 'walle'

android {
    compileSdkVersion 28



    defaultConfig {
        applicationId "com.example.administrator.dabao"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }


    buildTypes {
        release {
            shrinkResources true
            minifyEnabled true
            signingConfig signingConfigs.create("release")
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    signingConfigs {
        release {
            v2SigningEnabled true
            storeFile file("F:\\Android_studio\\keystore\\android.keystore")
            storePassword "123456"
            keyAlias "key0"
            keyPassword "123456"
        }
    }



}

walle {
    // 指定渠道包的输出路径
    apkOutputFolder = new File("${project.buildDir}/outputs/channels");
    // 定制渠道包的APK的文件名称
    apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
    // 渠道配置文件
    channelFile = new File("${project.getProjectDir()}/channel")
}


dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    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'

    debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.3'
    releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'

    implementation 'com.meituan.android.walle:library:1.1.6'

}

你可能感兴趣的:(多渠道打包的两种方式总结)