Android 使用Gradle進行多渠道打包詳解

一、爲什麼需要多渠道打包?

現在App會上架很多應用商店如:應用寶、小米、華爲等,我們需要統計應用商店註冊量、下載量等就需要在App中寫一個標識然後傳給後臺進行統計這樣的操作就需要用到多渠道打包。

二、爲什麼不用傳統打包方式?

假如現在我們要上架11個應用市場那麼我們就要手動打包11次修改標識11次這樣重複的操作很容易出錯並且也不方便。

三、解決方案

經過我多方調研決定用Gradle進行多渠道打包。

1、在AndroidMainfest中Application標籤下配置meta-data標籤
 <meta-data
            android:name="CHANNEL"
            android:value="${CHANNEL_VALUE}" />
2、在Gradle中Android標籤下配置
  /*配置渠道*/
    productFlavors {
        華爲 {
            manifestPlaceholders = [CHANNEL_VALUE: "huawei"]
        }
        小米 {
            manifestPlaceholders = [CHANNEL_VALUE: "xiaomi"]
        }
//
        應用寶 {
            manifestPlaceholders = [CHANNEL_VALUE: "yingyongbao"]
        }
        '360' {
            manifestPlaceholders = [CHANNEL_VALUE: "360"]
        }
        oppo {
            manifestPlaceholders = [CHANNEL_VALUE: "btwj1018oppo"]
        }
        vivo {
            manifestPlaceholders = [CHANNEL_VALUE: "vivo"]
        }
        魅族 {
            manifestPlaceholders = [CHANNEL_VALUE: "meizhu"]
        }
        三星 {
            manifestPlaceholders = [CHANNEL_VALUE: "sanxing"]
        }
        豌豆莢 {
            manifestPlaceholders = [CHANNEL_VALUE: "wandoujia"]
        }
    }
3、如需配置輸出路徑和apk名稱可在Android標籤下配置
buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            zipAlignEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            // 自定義輸出配置
            applicationVariants.all { variant ->
                variant.outputs.all { output ->
                    outputFileName = "app_name_${variant.productFlavors[0].name}_${releaseTime()}.apk"
                }
            }
        }
        }

在gradle中配置releaseTime()

//獲取編譯時間
static def releaseTime() {
    return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
5、如果配置成功遇到如下錯誤

在這裏插入圖片描述
如果在配置成功後遇到如下錯誤則在defaultConfig標籤中配置flavorDimensions "versionCode"

6、配置示例

AndroidManifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   >
  <application>
        <meta-data
            android:name="CHANNEL"
            android:value="${CHANNEL_VALUE}" />
    </application>

</manifest>

Gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"
    defaultConfig {
        applicationId "com.xxxxxxx.xxxxx"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        multiDexEnabled true
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        flavorDimensions "versionCode"
    }
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            zipAlignEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            // 自定義輸出配置
            applicationVariants.all { variant ->
                variant.outputs.all { output ->
                    outputFileName = "app_name_${variant.productFlavors[0].name}_${releaseTime()}.apk"
                }
            }
        }
        debug {
            minifyEnabled false
//            shrinkResources true
//            zipAlignEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }

    }
    compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    }
    /*配置渠道*/
    productFlavors {
        華爲 {
            manifestPlaceholders = [CHANNEL_VALUE: "huawei"]
        }
        小米 {
            manifestPlaceholders = [CHANNEL_VALUE: "xiaomi"]
        }
        '360' {
            manifestPlaceholders = [CHANNEL_VALUE: "360"]
        }
        oppo {
            manifestPlaceholders = [CHANNEL_VALUE: "oppo"]
        }
        vivo {
            manifestPlaceholders = [CHANNEL_VALUE: "vivo"]
        }
    }
}
//獲取編譯時間
static def releaseTime() {
    return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

7、獲取標識
 public static String getChannel(Context context) {
        try {
            PackageManager manager = context.getPackageManager();
            ApplicationInfo appInfo = manager.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
            return appInfo.metaData.getString("CHANNEL");
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return "";
        }
    }
8、打包

在這裏插入圖片描述
每次打包的時候直接選擇包就可以了也可以使用gradlew assembleRelease進行批量打包。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章