成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Gradle系列-運(yùn)用篇

jifei / 2350人閱讀

摘要:例如默認(rèn)配置項(xiàng)簽名相關(guān)構(gòu)建變體產(chǎn)品風(fēng)格源集配置等。例如你想修改為的名稱,這時(shí)你可以使用這樣在下的包名都是以打頭會(huì)幫助我們創(chuàng)建默認(rèn)的源集與目錄位于,用來(lái)存儲(chǔ)所有構(gòu)建變體間的共享資源。

上次我們說(shuō)到gradle的原理,主要是偏理論上的知識(shí)點(diǎn),直通車在這Android Gradle系列-原理篇。這次我們來(lái)點(diǎn)實(shí)戰(zhàn)的,隨便鞏固下之前的知識(shí)點(diǎn)。

android

在app module下的gradle.build中都有一個(gè)android閉包,主要配置都在這里設(shè)置。例如默認(rèn)配置項(xiàng):defaultConfig;簽名相關(guān):signingConfig;構(gòu)建變體:buildTypes;產(chǎn)品風(fēng)格:productFlavors;源集配置:sourceSets等。

defaultConfig

對(duì)于defaultConfig其實(shí)它是也一個(gè)productFlavor,只不過(guò)這里是用來(lái)提供默認(rèn)的設(shè)置項(xiàng),如果之后的productFlavor沒(méi)有特殊指定的配置都會(huì)使用defaultConfig中的默認(rèn)配置。

public class DefaultConfig extends BaseFlavor {
    @Inject
    public DefaultConfig(
            @NonNull String name,
            @NonNull Project project,
            @NonNull ObjectFactory objectFactory,
            @NonNull DeprecationReporter deprecationReporter,
            @NonNull Logger logger) {
        super(name, project, objectFactory, deprecationReporter, logger);
    }
}
 
public abstract class BaseFlavor extends DefaultProductFlavor implements CoreProductFlavor {
    ...
}

可以看到defaultConfig的超級(jí)父類就是DefaultProductFlavor。而在DefaultProductFlavor中定義了許多我們經(jīng)常見(jiàn)到的配置:VersionCode、VersionName、minSdkVersion、targetSdkVersion與applicationId等等。

有了上面的基礎(chǔ),那么在defaultConfig中我們要配置的變量就顯而易見(jiàn)了。

    defaultConfig {
        applicationId "com.idisfkj.androidapianalysis"
        minSdkVersion 16
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
signingConfigs

signingConfig是用來(lái)配置keyStore,我們可以針對(duì)不同的版本配置不同的keyStore,例如

    signingConfigs {
        config { //默認(rèn)配置
            storeFile file("key.store")
            storePassword "android123"
            keyAlias "android"
            keyPassword "android123"
        }
        dev { //dev測(cè)試版配置
            storeFile file("xxxx")
            storePassword "xxx"
            keyAlias "xxx"
            keyPassword "xxx"
        }
    }

有人可能會(huì)說(shuō)這不安全的,密碼都是明文,都暴露出去了。是的,如果這項(xiàng)目發(fā)布到遠(yuǎn)程,那么這些秘鑰就泄露出去了。所以為了安全起見(jiàn),我們可以對(duì)其進(jìn)一些特殊處理。

通過(guò)環(huán)境變量獲取秘鑰

storePassword System.getenv("KSTOREPWD")
keyPassword System.getenv("KEYPWD")

從命令行中獲取秘鑰

storePassword System.console().readLine("
Keystore password: ")
keyPassword System.console().readLine("
Key password: ")

上面兩種是Android Develop官網(wǎng)提供的,但經(jīng)過(guò)測(cè)試都會(huì)報(bào)null異常,查了下資料都說(shuō)是gradle不支持(如果有成功的可以告知我),所以還是推薦下面的這種方法

在項(xiàng)目的根目錄下(settings.gradle平級(jí))創(chuàng)建keystore.properties文件,我們?cè)谶@個(gè)文件中進(jìn)行存儲(chǔ)秘鑰,它是支持key-value模式的鍵值對(duì)數(shù)據(jù)

storePassword = android123
keyPassword = android123

之后就是讀取其中的password,在build.gradle通過(guò)afterEvaluate回調(diào)進(jìn)行讀取與設(shè)置

afterEvaluate {
    def propsFile = rootProject.file("keystore.properties")
    def configName = "config"
    if (propsFile.exists() && android.signingConfigs.hasProperty(configName)) {
        def props = new Properties()
        props.load(new FileInputStream(propsFile))
        android.signingConfigs[configName].keyPassword = props["keyPassword"]
        android.signingConfigs[configName].storePassword = props["storePassword"]
    }
}

我們已經(jīng)通過(guò)動(dòng)態(tài)讀取了password,所以在之前的signingConfigs中就無(wú)需再配置password

    signingConfigs {
        config {
            storeFile file("key.store")
            keyAlias "android"
        }
    }

最后一步,為了保證秘鑰的安全性,在.gitignore中添加keystore.properties的忽略配置,防止上傳到遠(yuǎn)程倉(cāng)儲(chǔ)暴露秘鑰。

buildTypes

構(gòu)建變體主要用來(lái)配置shrinkResources:資源是否需要壓縮、zipAlignEnabled:壓縮是否對(duì)齊、minifyEnabled:是否代碼混淆與signingConfig:簽名配置等等。新建項(xiàng)目時(shí),默認(rèn)有一個(gè)release配置,但我們實(shí)際開(kāi)發(fā)中可能需要多個(gè)不同的配置,例如debug模式,為了方法調(diào)試,一般都不需要對(duì)其進(jìn)行代碼混淆、壓縮等處理?;蛘遫uter模式,需要的簽名配置不同,所以最終的配置可以是這樣:

    buildTypes {
        debug {
            minifyEnabled false
            zipAlignEnabled false
            shrinkResources false
            signingConfig signingConfigs.config
        }
        outer {
            minifyEnabled false
            zipAlignEnabled false
            shrinkResources false
            signingConfig signingConfigs.outConfig
        }
        release {
            minifyEnabled true
            zipAlignEnabled true
            shrinkResources true
            signingConfig signingConfigs.config
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }

Sync Now之后,打開(kāi)Android Studio 右邊的Gradle,找到app->Tasks->build,發(fā)現(xiàn)已經(jīng)添加了assembleDebug與assembleOuter構(gòu)建task。

productFlavors

一個(gè)項(xiàng)目可能有不同的版本環(huán)境,例如開(kāi)發(fā)功能中的開(kāi)發(fā)版、項(xiàng)目上線的正式版。開(kāi)發(fā)版與正式版請(qǐng)求的數(shù)據(jù)api可能不同,對(duì)于這種情況我們就可以使用productFlavor來(lái)構(gòu)建不同的產(chǎn)品風(fēng)格,可以看下面的dev與prod配置

    flavorDimensions "mode"
    productFlavors {
        dev {
            applicationIdSuffix ".dev"
            dimension "mode"
            manifestPlaceholders = [PROJECT_NAME: "@string/app_name_dev",
                                    APP_ID      : "21321843"]
            buildConfigField "String", "API_URL", ""https://dev.idisfkj.android.com""
            buildConfigField "String", "APP_KEY", ""3824yk32""
        }
        prod {
            applicationIdSuffix ".prod"
            dimension "mode"
            manifestPlaceholders = [PROJECT_NAME: "@string/app_name",
                                    APP_ID      : "12932843"]
            buildConfigField "String", "API_URL", ""https://prod.idisfkj.android.com""
            buildConfigField "String", "APP_KEY", ""32143dsk2""
        }
    }

對(duì)于判斷是否為同一個(gè)app,手機(jī)系統(tǒng)是根據(jù)app的applicationId來(lái)識(shí)別的,默認(rèn)applicationId是packageName。所以為了讓dev與prod的版本都能共存在一個(gè)手機(jī)上,可以通過(guò)applicationIdSuffix來(lái)為applicationId增加后綴,改變安裝包的唯一標(biāo)識(shí)。

還有可以通過(guò)manifestPlaceholders來(lái)配置可用于AndroidManifest中的變量,例如根據(jù)不同的產(chǎn)品風(fēng)格顯示不同的app名稱

dev與prod網(wǎng)絡(luò)請(qǐng)求時(shí)使用不同的api host,可以設(shè)置buildConfigField,這樣我們就可以在代碼中通過(guò)BuildConfig獲取

    fun getApiUlr(): String {
        return BuildConfig.API_URL
    }

這里的BuildConfig會(huì)根據(jù)你構(gòu)建的產(chǎn)品風(fēng)格返回不同的值,它位于build->generated->source->buildConfig->變體,大致內(nèi)容如下:

public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String APPLICATION_ID = "com.idisfkj.androidapianalysis.dev";
  public static final String BUILD_TYPE = "debug";
  public static final String FLAVOR = "devMinApi21";
  public static final int VERSION_CODE = 20001;
  public static final String VERSION_NAME = "1.0-minApi21";
  public static final String FLAVOR_mode = "dev";
  public static final String FLAVOR_api = "minApi21";
  // Fields from product flavor: dev
  public static final String API_URL = "https://dev.idisfkj.android.com";
  public static final String APP_KEY = "3824yk32";
}

Sync Now之后,打開(kāi)Android Studio 右邊的Gradle,找到app->Tasks->build,發(fā)現(xiàn)新添加了assembleDev與assembleProd構(gòu)建task。

flavorDimensions是用來(lái)設(shè)置多維度的,上面的例子只展示了一個(gè)維度,所以dimension為mode的形式。我們新增一個(gè)api維度,構(gòu)建不同的minSkdVerison版本的apk

    flavorDimensions "mode", "api"
    productFlavors {
        dev {
            applicationIdSuffix ".dev"
            dimension "mode"
            manifestPlaceholders = [PROJECT_NAME: "@string/app_name_dev",
                                    APP_ID      : "21321843"]
            buildConfigField "String", "API_URL", ""https://dev.idisfkj.android.com""
            buildConfigField "String", "APP_KEY", ""3824yk32""
        }
        prod {
            applicationIdSuffix ".prod"
            dimension "mode"
            manifestPlaceholders = [PROJECT_NAME: "@string/app_name",
                                    APP_ID      : "12932843"]
            buildConfigField "String", "API_URL", ""https://prod.idisfkj.android.com""
            buildConfigField "String", "APP_KEY", ""32143dsk2""
        }
        minApi16 {
            dimension "api"
            minSdkVersion 16
            versionCode 10000 + android.defaultConfig.versionCode
            versionNameSuffix "-minApi16"
        }
        minApi21 {
            dimension "api"
            minSdkVersion 21
            versionCode 20000 + android.defaultConfig.versionCode
            versionNameSuffix "-minApi21"
        }
    }

gradle創(chuàng)建的構(gòu)建變體數(shù)量等于每個(gè)風(fēng)格維度中的風(fēng)格數(shù)量與你配置的構(gòu)建類型數(shù)量的乘積,所以上面例子的構(gòu)建變體數(shù)量為12個(gè)。在gradle為每個(gè)構(gòu)建變體或?qū)?yīng)apk命名時(shí),屬于較高優(yōu)先級(jí)風(fēng)格維度的產(chǎn)品風(fēng)格首先顯示,之后是較低優(yōu)先級(jí)維度的產(chǎn)品風(fēng)格,再之后是構(gòu)建類型。而優(yōu)先級(jí)的判斷則以flavorDimensions的值順序?yàn)橐罁?jù),以上面的構(gòu)建配置為例:

構(gòu)建變體:dev, prod[debug, outer, release]
對(duì)應(yīng)apk:app-[dev, prod]-[minApi16, minApi21]-[debug, outer, release].apk

構(gòu)建變體有這么多,但有時(shí)我們并不全部需要,例如你不需要mode為dev,api為minApi16的變體,這時(shí)你就可以使用variantFilter方法來(lái)過(guò)濾

    variantFilter { variant ->
        def names = variant.flavors*.name
        if (names.contains("minApi16") && names.contains("dev")) {
            setIgnore(true)
        }
    }

你再回到app->Tasks中查看變體,會(huì)發(fā)現(xiàn)已經(jīng)將devMinApi16相關(guān)的變體過(guò)濾了。

你不僅可以過(guò)濾構(gòu)建變體,還可以改變默認(rèn)的apk輸出名稱。例如你想修改buildType為release的apk名稱,這時(shí)你可以使用android.applicationVariants.all

    android.applicationVariants.all { variant ->
        if (variant.buildType.name == buildTypes.release.name) {
            variant.outputs.all {
                outputFileName = "analysis-release-${defaultConfig.versionName}.apk"
            }
        }
    }

這樣在release下的包名都是以analysis打頭

sourceSets

Android Studio會(huì)幫助我們創(chuàng)建默認(rèn)的main源集與目錄(位于app/src/main),用來(lái)存儲(chǔ)所有構(gòu)建變體間的共享資源。所以你可以通過(guò)設(shè)置main源集來(lái)更改默認(rèn)的配置。例如現(xiàn)在你想將res的路徑修改成src/custom/res

    sourceSets {
        main {
            res.srcDirs = ["src/custom/res"]
        }
    }

這樣res資源路徑就定位到了src/custom/res下,當(dāng)然你也可以修改其它的配置,例如java、assets、jni等。

如果你配置了多個(gè)路徑,即路徑集合:

    sourceSets {
        main {
            res.srcDirs = ["src/custom/res", "scr/main/res"]
        }
    }

這時(shí)你要保證不能有相同的名稱,即每個(gè)文件只能唯一存在其中一個(gè)目錄下。

你也可以查看所以的構(gòu)建變體的默認(rèn)配置路徑: 點(diǎn)擊右邊gradle->app->android->sourceSets,你將會(huì)看到如下類似信息

------------------------------------------------------------
Project :app
------------------------------------------------------------
 
androidTest
-----------
Compile configuration: androidTestCompile
build.gradle name: android.sourceSets.androidTest
Java sources: [app/src/androidTest/java]
Manifest file: app/src/androidTest/AndroidManifest.xml
Android resources: [app/src/androidTest/res]
Assets: [app/src/androidTest/assets]
AIDL sources: [app/src/androidTest/aidl]
RenderScript sources: [app/src/androidTest/rs]
JNI sources: [app/src/androidTest/jni]
JNI libraries: [app/src/androidTest/jniLibs]
Java-style resources: [app/src/androidTest/resources]
...

上面是androidTest變體的默認(rèn)路徑,首先它會(huì)去查找相應(yīng)的構(gòu)建變體的默認(rèn)位置,如果沒(méi)有找到,就會(huì)使用main源集下的默認(rèn)配置。也就是我們所熟悉的app/src/main路徑下的資源。

因?yàn)樗歉鷺?gòu)建變體來(lái)搜索的,所以它有個(gè)優(yōu)先級(jí):

src/modeApiDebug: 構(gòu)建變體

src/debug:構(gòu)建類型

src/modeApi:產(chǎn)品風(fēng)格

src/main:默認(rèn)main源

對(duì)于源集的創(chuàng)建,如下所示在app/src下右鍵新建,但它只會(huì)幫你創(chuàng)建源集下的java文件夾,其它的都要你自己逐個(gè)創(chuàng)建

我們自定義一個(gè)debug源集,所以進(jìn)去之后Target Source Set選擇debug,再點(diǎn)擊finish結(jié)束。這時(shí)你將會(huì)在src下看到debug文件夾

現(xiàn)在你已經(jīng)有了debug的源集目錄,假設(shè)你現(xiàn)在要使debug下的app名稱展示成Android精華錄debug(默認(rèn)是Android精華錄)。這時(shí)你可以右鍵debug新建values

在values目錄下新建strings.xml,然后在其中配置app_name



    Android精華錄debug

最后你再去構(gòu)建debug相關(guān)的變體時(shí),你安裝的app展示的名稱將是Android精華錄debug。

所以通過(guò)修改mian源集或者配置其它的變體源集,可以實(shí)現(xiàn)根據(jù)變體加載不同的數(shù)據(jù)源。這樣系統(tǒng)化的配置加載資源將更加方便項(xiàng)目測(cè)試與版本需要的配置。

dependencies

dependencies閉包上用來(lái)配置項(xiàng)目的第三方依賴,如果你根據(jù)上面的配置有設(shè)置變體,那么你將可以根據(jù)變體來(lái)選擇性的依賴第三方庫(kù)

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    implementation "com.android.support:appcompat-v7:26.1.0"
    implementation "com.android.support.constraint:constraint-layout:1.0.2"
    testImplementation "junit:junit:4.12"
    androidTestImplementation "com.android.support.test:runner:1.0.1"
    androidTestImplementation "com.android.support.test.espresso:espresso-core:3.0.1"
    //根據(jù)變體選擇性依賴
    outerImplementation "..."
    prodMinApi21Implementation "..."
}

關(guān)于dependencies,這只是簡(jiǎn)單的配置方式,之后我還會(huì)多帶帶抽出一篇文章來(lái)寫(xiě)系統(tǒng)化的配置dependencies,感興趣的可以關(guān)注下。

gradle相關(guān)的配置還有很多,這里只是冰山一角,但我的建議是根據(jù)你的實(shí)際需求去學(xué)習(xí)與研究,相信你也會(huì)有意想不到的成長(zhǎng)。

最后附上源碼地址:https://github.com/idisfkj/an...

博客地址:https://www.rousetime.com/

系列

Android Gradle系列-入門篇

Android Gradle系列-原理篇

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/74703.html

相關(guān)文章

  • Android Gradle系列-進(jìn)階

    摘要:如果你有新建一個(gè)項(xiàng)目的經(jīng)歷,那么你將看到推薦的方案在的中使用來(lái)定義版本號(hào)全局變量。例如之前的版本號(hào)就可以使用如下方式實(shí)現(xiàn)因?yàn)槭褂玫氖钦Z(yǔ)言,所以以上都是語(yǔ)法例如版本控制,上面代碼的意思就是將有個(gè)相關(guān)的版本依賴放到的變量中,同時(shí)放到了中。 showImg(https://segmentfault.com/img/bVbsh3m?w=2560&h=1280); 上篇文章我們已經(jīng)將Gradle...

    lvzishen 評(píng)論0 收藏0
  • Android Gradle系列-入門

    摘要:接下來(lái)的一段時(shí)間會(huì)對(duì)的相關(guān)知識(shí)進(jìn)行梳理,所以借此整理成一個(gè)系列。所以不僅支持還支持等。所以是位于的最外層,即與同級(jí)。根據(jù)后面的提示,發(fā)現(xiàn)它們分別來(lái)自與與。它會(huì)在運(yùn)行時(shí)注入到相應(yīng)的中。 showImg(https://segmentfault.com/img/bVbsh3m?w=2560&h=1280); 接下來(lái)的一段時(shí)間會(huì)對(duì)Android Gradle的相關(guān)知識(shí)進(jìn)行梳理,所以借此整理成...

    spademan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<