一.Gradle多渠道打包使用多个.gradle文件

 

1.简介

上述章节讲述了,多渠道打包时,配置不同包的不同配置。但这些不同的配置都是在APP的Gradle文件中声明的,如果渠道多了,然后不同的配置也多了。那么APP的Gradle文件代码就会特别多,也会显得特别乱。我们可以分开不同的文件,根据不同的渠道来加载不同文件夹中的属性。

 

 

 

2.文件截图

Android gradle task没了_Gradle脚本打包

blue.properties文件

#blue包
#Url配置
HOST_URL=https://aaa.bbb.ccc.blue:1234
#PROVIDER配置
PROVIDER=com.wjn.okhttpmvpdemo.blue
#MAPKEY
KEY_MAP=sdfasfds2345dfafFDg_Blue

red.properties文件

#red包
#Url配置
HOST_URL=https://aaa.bbb.ccc.red:4321
#PROVIDER配置
PROVIDER=com.wjn.okhttpmvpdemo.red
#MAPKEY
KEY_MAP=sdfasfds2345dfafFDg_Red

 

 

 

3.代码

APP的Gradle文件

apply plugin: 'com.android.application'

/** ext闭包 在本Gradle中配置 versionCode&versionName 本Gradle的defaultConfig{}包使用 */
ext {
    versionInt = 2
    versionString = "2.0.0"
    releaseTime = releaseTime()
}

android {

    compileSdkVersion 28
    /** defaultConfig闭包 默认配置 */
    defaultConfig {
        applicationId "com.wjn.okhttpmvpdemo"
        minSdkVersion 19
        targetSdkVersion 27
        versionCode versionInt
        versionName versionString
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    /** signingConfigs闭包 项目签名配置 */
    signingConfigs {
        release {
            storeFile file('C:\\Users\\wujianning\\AndroidStudioProjects\\demo\\OKHttpMVPDemo\\test.jks')
            storePassword '123456'
            keyAlias 'key0'
            keyPassword '123456'
            v1SigningEnabled true
            v2SigningEnabled true
        }

        debug {
            storeFile file('C:\\Users\\wujianning\\AndroidStudioProjects\\demo\\OKHttpMVPDemo\\test.jks')
            storePassword '123456'
            keyAlias 'key0'
            keyPassword '123456'
            v1SigningEnabled true
            v2SigningEnabled true
        }
    }

    /** buildTypes闭包 项目打包配置 比如是否混淆 是否压缩 是否支持调式等等 这里为了区分下面多渠道打包Debug包和Release包 在versionName后添加了不同的后缀*/
    buildTypes {
        release {
            minifyEnabled false
            debuggable false
            multiDexEnabled false
        }

        debug {
            minifyEnabled false
            debuggable true
            multiDexEnabled false
            buildConfigField "String", "MAPID", "\"" + rootProject.ext.android.mapId + "\""
        }
    }

    /** productFlavors闭包 多渠道打包 flavorDimensions属性确定维度 分支&免费付费 */
    flavorDimensions "branch", "free_pay"
    productFlavors {
        red {
            dimension "branch"
            signingConfig signingConfigs.release
            //加载不同的Gradle文件 这里加载red.properties文件
            Properties branch_config = loadConfigGradle("red")
            buildConfigField("String", "HOST_URL", "\"${branch_config['HOST_URL']}\"")
            getManifestPlaceholders().put("PROVIDER", "${branch_config['PROVIDER']}")
            getManifestPlaceholders().put("KEY_MAP", "${branch_config['KEY_MAP']}")
        }

        blue {
            dimension "branch"
            signingConfig signingConfigs.debug
            //加载不同的Gradle文件 这里加载red.properties文件
            Properties branch_config = loadConfigGradle("blue")
            buildConfigField("String", "HOST_URL", "\"${branch_config['HOST_URL']}\"")
            getManifestPlaceholders().put("PROVIDER", "${branch_config['PROVIDER']}")
            getManifestPlaceholders().put("KEY_MAP", "${branch_config['KEY_MAP']}")
        }

        free {
            dimension "free_pay"
            buildConfigField "boolean", "IS_FREE", "true"
        }

        pay {
            dimension "free_pay"
            buildConfigField "boolean", "IS_FREE", "false"
        }
    }

    /** variantFilter闭包 过滤变体 可以设置忽略那个包 比如这里过滤掉了不在列表中的包*/
    variantFilter { variant ->
        def needed = variant.name in [
                'redFreeRelease',
                'redFreeDebug',
                'redPayRelease',
                'redPayDebug',
                'blueFreeRelease',
                'blueFreeDebug',
                'bluePayRelease',
                'bluePayDebug',
        ]
        setIgnore(!needed)
    }

    /** compileOptions闭包 配置项目使用JDK1.8 */
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    /** applicationVariants闭包 配置项目打包包名 */
    android.applicationVariants.all {
        variant ->
            variant.outputs.all { output ->
                //获取分支 red&blue
                def appBranch = variant.productFlavors[0].name
                //获取免费付费  free&pay
                def free_pay = variant.productFlavors[1].name
                //默认的包名
                def result = "OkHttp_" + versionString
                //操作包名 blue的包 拼后面的字符串 red的包使用默认的字符串不需要拼后面的字符串
                if (appBranch == "blue") {
                    result = result + "_" + free_pay.toUpperCase() + "_" + releaseTime() + ".apk"
                } else {
                    result = result + ".apk"
                }
                //更新打出的包的名称
                outputFileName = result
                //更新VersionName
                output.setVersionNameOverride(result)
            }
    }

    /** sourceSets闭包 配置项目文件 */
    sourceSets {

        /** 默认 配置项目文件 */
        main {
            jniLibs.srcDirs = ['libs']
            assets.srcDirs = ['src/main/assets']
        }

        /** blue包 配置项目文件 */
        blue {
            assets.srcDirs = ['../protectFileConfig/assets/blue']
        }

        /** red包 配置项目文件 */
        red {
            assets.srcDirs = ['../protectFileConfig/assets/red']
        }

    }

}

static def releaseTime() {
    return new Date().format("yyyyMMdd", TimeZone.getTimeZone("GMT+8"))
}

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'
    implementation 'com.android.support:support-v4:27.1.1'
    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 'io.reactivex:rxjava:1.3.2'
    implementation 'io.reactivex:rxandroid:1.2.1'
    implementation 'com.squareup.okhttp3:okhttp:3.9.0'
    implementation 'com.squareup.okhttp3:logging-interceptor:3.6.0'
    implementation 'com.readystatesoftware.systembartint:systembartint:1.0.3'

    implementation 'com.squareup.retrofit2:retrofit:2.7.0'
    implementation 'com.github.bumptech.glide:glide:4.4.0'
}

/** loadConfigGradle方法 用来加载不同的gradle文件 */
def loadConfigGradle(name) {
    Properties props = new Properties()
    FileInputStream fis = new FileInputStream(file("../protectFileConfig/gradle/" + name + ".properties"))
    BufferedReader bf = new BufferedReader(new InputStreamReader(fis, "UTF-8"))
    props.load(bf)
    return props
}

 

清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.wjn.okhttpmvpdemo">

   

    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!-- provider的authorities属性 使用PROVIDER占位符 -->
        <provider
            android:name=".MyContentProvider"
            android:authorities="${PROVIDER}.provider"
            android:enabled="true"
            android:exported="false">

        </provider>

        
        <activity android:name=".view.impl.activity.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- meta-data的value值 使用KEY_MAP占位符 -->
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="${KEY_MAP}"/>

    </application>

</manifest>

 

Java代码

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String HOST_URL = BuildConfig.HOST_URL;
        Log.d("MainActivity", "HOST_URL----:" + HOST_URL);
    }

}

 

 

4.验证

打两个包验证 OkHttp_2.0.0_FREE_20170428.apk和OkHttp_2.0.0.apk。截图

Android gradle task没了_Gradle多渠道打包_02

 

OkHttp_2.0.0_FREE_20170428.apk包

清单文件

<provider
     android:name="com.wjn.okhttpmvpdemo.MyContentProvider"
     android:enabled="true"
     android:exported="false"
      
     android:authorities="com.wjn.okhttpmvpdemo.blue.provider" />


<meta-data
     android:name="com.google.android.maps.v2.API_KEY"
     
     android:value="sdfasfds2345dfafFDg_Blue" />

 

日志

D/MainActivity: HOST_URL----:https://aaa.bbb.ccc.blue:1234

 

 

OkHttp_2.0.0.apk包

清单文件

<provider
     android:name="com.wjn.okhttpmvpdemo.MyContentProvider"
     android:enabled="true"
     android:exported="false"
     
     android:authorities="com.wjn.okhttpmvpdemo.red.provider" />



<meta-data
     android:name="com.google.android.maps.v2.API_KEY"
     
     android:value="sdfasfds2345dfafFDg_Red" />

 

日志

D/MainActivity: HOST_URL----:https://aaa.bbb.ccc.red:4321

 

 

5.注意

上述在多渠道时,在两个渠道都加载了不同的properties文件,如果有多个渠道需要在每一个渠道写一份代码,而每一份的代码仅仅是加载的properties名字不一样。我们可以有更简洁的写法。

/** productFlavors闭包 多渠道打包 简洁写法 */
productFlavors.all { flavor ->
    def name = flavor.name//name可能的值:red blue free pay 所以要过滤一下
    if (name == "red" || name == "blue") {
        //加载不同的Gradle文件 加载name.properties文件
        Properties branch_config = loadConfigGradle(name)
        buildConfigField("String", "HOST_URL", "\"${branch_config['HOST_URL']}\"")
        getManifestPlaceholders().put("PROVIDER", "${branch_config['PROVIDER']}")
        getManifestPlaceholders().put("KEY_MAP", "${branch_config['KEY_MAP']}")
    }
}