SHO酱的Blog

SHO酱的Blog

Android针对不同渠道使用不同配置

2019-02-13

Android Studio Icon

使用 meta-data 区分渠道

  • build.gradle中定义productFlavors
productFlavors {
    xiaomi {
        manifestPlaceholders = [
            UMENG_CHANNEL_VALUE: "xiaomi",
        ]
    }
    qq {
        manifestPlaceholders = [
            UMENG_CHANNEL_VALUE: "qq",
        ]
    }
}
  • AndroidManifest.xml中定义<meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_VALUE}"/>
<application
    android:name=".YunboxApplication"
    android:allowBackup="true"
    android:icon="@mipmap/icon_new"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.NoTitleBar">
    ...
    <meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_VALUE}"/>
    ...
</application>

  • Application中使用 meta-data
ApplicationInfo applicationInfo = null;
try {
    applicationInfo = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException e) {
    e.printStackTrace();
}
if (applicationInfo == null) {
    channel = "Default";
    return;
}
channel = applicationInfo.metaData.getString("UMENG_CHANNEL");

使用 buildConfigField 定义各渠道变量的值

在发布apk文件后,会需要根据不同渠道某些变量或常量的值也不同,除了可以向上面使用meta-data方法给变量赋予不同的值以外,还可以通过buildConfigFieldBuildConfig中直接定义不同值的常量。

productFlavors {
    xiaomi {
        buildConfigField "String","INTERFACE_URL_PIX",""http://www.xiaomi.com""
        manifestPlaceholders = [
            UMENG_CHANNEL_VALUE: "xiaomi",
        ]
    }
    qq {
        buildConfigField "String","INTERFACE_URL_PIX",""http://www.qq.com""
        manifestPlaceholders = [
            UMENG_CHANNEL_VALUE: "qq",
        ]
    }
}

如上定义buildConfigField后,编译工程后会在app/generatedJava中生成com.zhongcaile.yunbox.BuildConfig类中添加public static final String INTERFACE_URL的定义。全部代码如下:

public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String APPLICATION_ID = "com.zhongcaile.yunbox";
  public static final String BUILD_TYPE = "debug";
  public static final String FLAVOR = "jtd";
  public static final int VERSION_CODE = 112;
  public static final String VERSION_NAME = "1.8.12";
  // Fields from product flavor: jtd
  public static final String INTERFACE_URL_PIX = "http://www.xiaomi.com";
}

同样,通过buildConfigField还可以定义booleanint等类型的常量。如下:

buildConfigField("boolean", "LOG_DEBUG", "true")
buildConfigField "int", "VERSION_TYPE", "1"

定义渠道维度 flavorDimensions

关于维度没有读懂,待继续

  • 定义维度
android {
    compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
    buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION
    defaultConfig {
        ...
        flavorDimensions "channel"
    }
    ...
}
  • 使用维度
productFlavors {
    xiaomi {
        dimension "channel"
        buildConfigField "String","INTERFACE_URL_PIX",""http://www.xiaomi.com""
        manifestPlaceholders = [
            UMENG_CHANNEL_VALUE: "xiaomi",
        ]
    }
    qq {
        dimension "channel"
        buildConfigField "String","INTERFACE_URL_PIX",""http://www.qq.com""
        manifestPlaceholders = [
            UMENG_CHANNEL_VALUE: "qq",
        ]
    }
}

多渠道 APK 打包

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        // 自定义输出配置
        applicationVariants.all { variant ->
            variant.outputs.all { output ->
                outputFileName = "t_${variant.versionCode}_${defaultConfig.versionName}${variant.productFlavors[0].name}.apk"
            }
        }
    }
}

通过配置导出 APK 文件被命名为t_99_1.9.9xiaomi.apkt_99_1.9.9qq.apk

参考

Android Studio中的productFlavors指定默认编译执行的任务
浅谈Android中的meta-data及其应用
Android Studio3.0 flavorDimensions多维度理解(版本差异化打包)
Android Gradle进阶配置指南
Android build.gradle之productFlavors { }