android-AS-渠道包打包优化

基本原理

首先渠道包的基本打包实现:

在每个渠道包的manifest文件中配置一个meta-data的标签,写入对应的渠道数据
以友盟为例:

    <manifest>
        ... ...
        <meta-data
            android:name="UMENG_CHANNEL"
            android:value="${UMENG_CHANNEL_VALUE}" />
    manifest>

至于为什么是manifest而不是其他地方,个人认为是因为官方提供了直接读取的方式:

   /**
     * 获取app当前的渠道号或application中指定的meta-data
     *
     * @return 如果没有获取成功(没有对应值,或者异常),则返回值为空
     */
    public static String getAppMetaData(Context context, String key) {
        if (context == null || TextUtils.isEmpty(key)) {
            return null;
        }
        String channelNumber = null;
        try {
            PackageManager packageManager = context.getPackageManager();
            if (packageManager != null) {
                ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
                if (applicationInfo != null) {
                    if (applicationInfo.metaData != null) {
                        channelNumber = applicationInfo.metaData.getString(key);
                    }
                }
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return channelNumber;
    }

渠道示例

美团示例渠道
当前总共21个

gradle批量打包

实现方式

通过gradle的flavor循环打包。即假设有21个渠道,对每个渠道的manifest通过flavor配置,循环打包21次。
参看官方文档-配置构建变体

配置渠道信息

gradle中flavor的变量不能用数字开头
且新版需要加入dimension的概念

android{
    ... ...
    flavorDimensions "channel","someOther"
    productFlavors {
        meituan {flavorDimensions "channel"}
        samsungapps {flavorDimensions "channel"}
        ...
        productFlavors.all { flavor ->
            flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
        }
    }
}

这里的flavor.manifestPlaceholders可以将后面的UMENG_CHANNEL_VALUE赋值给manifest中的${UMENG_CHANNEL_VALUE}变量

获取渠道信息

直接在java代码中调用“基本原理”章节的方法即可,例如:

((TextView) findViewById(R.id.tv)).setText(getAppMetaData(this, "UMENG_CHANNEL"));

打包方式

1、手动在as的build-generate assigned apk 中进行点击

2、或者先在gradle中配置release:

android{
    ... ...
    signingConfigs{
        myConfig{
            keyAlias 'key0'
            keyPassword 'yourPassword'
            storeFile file('F:\\AndroidStudio\\demo.jks')
            storePassword 'yourPassword'
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.myConfig
        }
    }
}

在通过terminal即可(linux需要加./ , 具体的参数类型可以查看gradle面板–app–Tasks):
gradlew assembleRelease

文件默认位置:app/build/outputs,双击可以用AS自带功能解析:
android-AS-渠道包打包优化_第1张图片

打包时间

第一次执行,及第二次执行(未删除包):
android-AS-渠道包打包优化_第2张图片

美团方案实践

实现方式

通过gradle进行第一次打包(即正常打包,但不附带渠道信息),之后复制并直接修改manifest配置,即复制21次。
参看新一代开源Android渠道包生成工具Walle

配置渠道信息

参看美团开源-walle
添加依赖和插件(插件用于帮忙处理复制部分的操作)

读取渠道信息

WalleChannelReader.getChannel(this.getApplicationContext());

打包命令

gradlew clean assembleReleaseChannels
android-AS-渠道包打包优化_第3张图片

打包时间

同样是两次执行:
android-AS-渠道包打包优化_第4张图片

单次打包优化

参看章节官方文档-配置构建
或者直接查看小节官方文档–优化构建速度

参考文档

除了上述已经写入的链接:
android获取app当前的渠道号或者获取清单文件application中的任意meta-data(以友盟的多渠道打包为例)

你可能感兴趣的:(android-AS-渠道包打包优化)