天天看點

Gradle 翻譯 tips and recipes 使用技巧 [MD]

博文位址

我的GitHub 我的部落格 我的微信 我的郵箱
baiqiantao bqt20094 [email protected]

目錄

  • Gradle 提示與訣竅
    • 管理項目和源代碼
      • 更改預設源集配置:sourceSets
      • 配置項目範圍的屬性:ext
    • 管理庫和依賴項
      • 将依賴項配置針對特定建構:configurations
    • 建立不同版本的應用
      • 配置多 APK 支援:splits、density、abi
      • 配置動态版本代碼:android.applicationVariants.all
      • 組合多個産品風味:flavorDimensions
      • 過濾變體:variantFilter
    • 測試應用(不常用)
      • 配置 lint 選項:lintOptions
      • 配置儀器 manifest 設定:test**
      • 更改測試建構類型:testBuildType
      • 配置 Gradle 測試選項:testOptions
    • 優化您的建構
      • 壓縮代碼:ProGuard
      • 通過 Instant Run 啟用代碼壓縮:useProguard
      • 配置 DEX 選項:dexOptions
    • 釋出您的應用
      • 簽署您的應用:signingConfigs
      • 從您的項目中移除私密簽署資訊:.properties配置檔案
    • 簡化應用開發
      • 與代碼共享自定義字段和資源值:buildConfigField 和 resValue
      • 與 manifest 共享屬性:manifestPlaceholders

Gradle tips and recipes

Gradle

Android Plugin for Gradle

提供了一種靈活[flexible]的方式來編譯、建構和打包您的 Android 應用或庫。本頁面彙總了一些有用提示和配置,旨在幫助您充分利用每一個建構[get the most out of each build]。

[Manage projects and sources]

下面是一些可用于管理您的項目的子產品及其源代碼的配置。要詳細了解如何建立和管理項目與子產品,請閱讀 項目概覽。

[Change default source set configurations]

您可以使用子產品級

build.gradle

檔案中的

sourceSets

代碼塊更改 Gradle 希望為源集 的每個元件收集檔案的位置。

簡潔版:

android {
  sourceSets {
    main {
      java.srcDirs = ['other/java'] //預設為【src/main/java】
      res.srcDirs = ['other/res1', 'other/res2'] //預設為【src/main/res】
      manifest.srcFile 'other/AndroidManifest.xml' //預設為【src/main/AndroidManifest.xml】
    }
    androidTest {
      setRoot 'src/tests' //預設有三個根目錄【src/androidTest】【src/test】【src/main】
    }
  }
}
           

完整版:

android {
  sourceSets {
    main { // Encapsulates将包封 configurations for the main source set.
      java.srcDirs = ['other/java'] // Changes the directory for Java sources.
/** If you list multiple directories, Gradle uses all of them to collect sources. Because Gradle gives these directories equal priority, if you define the same resource in more than one directory, you get an error when merging resources. */
      res.srcDirs = ['other/res1', 'other/res2']

/** Note: You should avoid specifying a directory which is a 【parent】 to one or more other directories you specify. For example, avoid the following: res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings']. You should specify either only the root 'other/res1' directory, or only the nested 'other/res1/layouts' and 'other/res1/strings' directories. */

/** For each source set, you can specify only one Android manifest. By default, Android Studio creates a manifest for your main source set in the src/main/ directory. */
      manifest.srcFile 'other/AndroidManifest.xml'
    }

    androidTest {  // Create additional blocks to configure other source sets.

/** If all the files for a source set are located under a single root directory, you can specify that directory using the setRoot property. When gathering搜集 sources for the source set, Gradle looks only in locations relative to the root directory you specify. For example, after applying the configuration below for the androidTest source set, Gradle looks for Java sources only in the src/tests/java/ directory. */
      setRoot 'src/tests'
    }
  }
}
           

[configure project-wide properties]

對于包含多個子產品的項目,在項目級别定義屬性,然後在所有子產品間共享這些屬性可能會非常有用。為此,您可以将 extra properties 添加到 the top-level build.gradle 檔案的 ext 代碼塊中。

簡潔版

ext {
    compileSdkVersion = 26
    supportLibVersion = "27.1.1"
}
           

完整版

buildscript {...}

allprojects {...}

// This block encapsulates封裝 custom properties and makes them available to all modules in the project.
ext { // The following are only a few examples of the types of properties you can define.
    compileSdkVersion = 26
    // You can also create properties to specify versions for dependencies指定依賴項的版本.
    // Having consistent一緻的 versions between modules can avoid conflicts with behavior.
    supportLibVersion = "27.1.1"
    //...
}
           

要從相同項目中的子產品通路這些屬性,請在 module-level build.gradle 檔案中使用以下文法。

android {
  compileSdkVersion rootProject.ext.compileSdkVersion //文法【rootProject.ext.property_name】
}

dependencies {
    //文法【$rootProject.ext.property_name】或【${rootProject.ext.property_name}】
    compile "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
}
           

[Manage libraries and dependencies]

Gradle 提供了一種穩健的機制來管理依賴項,不管它們是遠端庫還是本地庫子產品。

[Target specific builds with dependency configurations]

如果您希望某個

依賴項

僅用于特定的

建構變體源集或者測試源集

,則必須

大寫依賴項配置名稱

并在其前面加上

建構變體或測試源集的名稱

作為字首。

If you want a dependency for only a specific

build variant source set or testing source set

, capitalize the dependency configuration name and prefix it with the name of the

build variant or testing source set

.
configurations {
    freeDebugRuntimeOnly{} //初始化配置名稱,用于指定具體是哪個建構(此名稱代表 free Debug 的建構)
    feeDebugImplementation{}
}

dependencies {
    freeDebugRuntimeOnly fileTree(dir: 'libs', include: ['*.jar']) //僅為指定建構添加此依賴
    feeDebugImplementation 'com.google.firebase:firebase-ads:9.8.0'
}
           
android {...}

// Creates Gradle dependency configurations to use in the dependencies block.
configurations {
  // For variants that combine a product flavor and build type, you need to intitialize a placeholder for its dependency configuration.
    freeDebugRuntimeOnly{}
  //...
}

dependencies {
    freeImplementation 'com.google.firebase:firebase-ads:9.8.0'  // Adds an implementation dependency only to the "free" product flavor.
    freeDebugRuntimeOnly fileTree(dir: 'libs', include: ['*.jar']) // Adds a runtimeOnly dependency only to the "freeDebug" build variant.
    testImplementation 'junit:junit:4.12' // Adds a remote binary dependency only for local tests.
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' // Adds a remote binary dependency only for the instrumented test APK.
}
           

[Create different versions of your app]

Gradle 和 Android 插件允許您通過配置建構變體的方式從一個子產品建立不同版本的應用。

[Configure multiple APK support]

利用 Android 插件,您可以建構多個 APK,讓每一個都針對不同的 ABI 或螢幕密度,并充分利用 Google Play 的多 APK 支援。

按螢幕密度配置單獨的 APK

[Configure separate APKs per screen density]

要為不同的螢幕密度建立單獨的 APK,請将

android.splits.density

代碼塊添加到您的子產品的 build.gradle 檔案中。

android {
  splits {
    density { // Configures multiple APKs based on screen density.
      enable true  // The default value is false
      exclude "ldpi", "xxhdpi", "xxxhdpi" //排除。Specifies a list of screen densities Gradle should not create multiple APKs for.
      compatibleScreens 'small', 'normal', 'large', 'xlarge'  //相容的 Specifies a list of compatible screen size settings for the manifest.
    }
  }
}
           

按 ABI 配置單獨的 APK

[Configure separate APKs per ABI]

要為每個 ABI 建立單獨的 APK,請将

android.splits.abi

android {
  splits {
    abi { // Configures multiple APKs based on ABI.
      enable true  // The default value is false
      // By default all ABIs are included, so use reset() and include to specify that we only want APKs for x86 and x86_64.
      reset() // Resets the list of ABIs that Gradle should create APKs for to none.
      include "x86", "x86_64"  // Specifies a list of ABIs that Gradle should create APKs for.
      universalApk false  // Specifies that we do not want to also generate a universal APK that includes all ABIs.
    }
  }
}
           

[Configure dynamic version codes]

預設情況下,在 Gradle 為您的項目生成 APK 時,每個 APK 都有相同的版本資訊,此資訊在子產品級 build.gradle 檔案中指定。由于 Google Play 商店不允許同一個應用的多個 APK 全都具有相同的版本資訊,在上傳到 Play 商店之前,您需要確定每個 APK 都有自己唯一的

versionCode

為此,您可以使用自定義建構邏輯在建構時向每個 APK 配置設定不同的版本代碼。例如,在為每個 ABI 建立單獨的 APK 時,自動 APK 版本控制将如下所示:

ext.abiCodes = ['armeabi-v7a':1, x86:2, x86_64:3]

import com.android.build.OutputFile
android.applicationVariants.all { variant -> 
  variant.outputs.each { output ->
    def baseAbiVersionCode = project.ext.abiCodes.get(output.getFilter(OutputFile.ABI))
    if (baseAbiVersionCode != null) {
       output.versionCodeOverride =  baseAbiVersionCode * 1000 + variant.versionCode
    }
  }
}
           
ext.abiCodes = ['armeabi-v7a':1, x86:2, x86_64:3]

import com.android.build.OutputFile
android.applicationVariants.all { variant -> 
  variant.outputs.each { output -> // Assigns a different version code for each output APK other than the universal APK.
    def baseAbiVersionCode = project.ext.abiCodes.get(output.getFilter(OutputFile.ABI))// Determines the ABI for this variant and returns the mapped value.

/** Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes, the following code does not override the version code for universal APKs. However, because we want universal APKs to have the lowest version code, this outcome is desirable令人滿意的. */
    if (baseAbiVersionCode != null) {
/** Assigns the new version code to versionCodeOverride, which changes the version code for only the output APK, not for the variant itself. Skipping this step simply causes隻會導緻 Gradle to use the value of variant.versionCode for the APK. */
      output.versionCodeOverride =  baseAbiVersionCode * 1000 + variant.versionCode
    }
  }
}
           

[Combine multiple product flavors]

某些情況下,您可能希望組合多個産品風味中的配置。為此,您可以通過 Android Plugin for Gradle 建立産品風味組,稱為風味次元。

下面的代碼示例使用 flavorDimensions 屬性建立一個“模式”風味次元以組織“完整”和“示範”産品風味,以及一個“api”風味次元以基于 API 級别組織産品風味配置。随後,Gradle 會将“模式”次元的産品風味與“api”次元的産品風味組合。

android {
  buildTypes {
    debug {...}
    release {...}
  }

  flavorDimensions "api", "mode"

  productFlavors {
    demo {
      dimension "mode"  //風味次元:mode
    }
    full {
      dimension "mode"  //風味次元:mode
    }

    minApi24 {
      dimension "api"  //風味次元:api
      minSdkVersion '24'
      versionCode 30000 + android.defaultConfig.versionCode
      versionNameSuffix "-minApi24"
    }
    minApi23 {...}  //風味次元:api
    minApi21 {...}  //風味次元:api
  }
}
           
android {
  buildTypes {
    debug {...}
    release {...}
  }

/** Specifies指定 the flavor dimensions you want to use. The order in which you list each dimension determines決定了 its priority優先級, from highest to lowest, when Gradle merges合并 variant sources and configurations. You must assign配置設定給 each product flavor you configure to one of the flavor dimensions. */
  flavorDimensions "api", "mode"

  productFlavors {
    demo {
      dimension "mode"  // Assigns this product flavor to the "mode" flavor dimension.
    }

    full {
      dimension "mode"
    }

/** Configurations in the "api" product flavors override覆寫 those in "mode" flavors and the defaultConfig {} block. Gradle determines确定 the priority between flavor dimensions based on根據 the order in which they appear next to the flavorDimensions property above--the first dimension has a higher priority than the second, and so on. */
    minApi24 {
      dimension "api"
      minSdkVersion '24'
/** To ensure the target device receives the version of the app with the highest compatible API level[要確定目标裝置接收具有最高相容API級别的應用程式版本], assign配置設定 version codes in increasing value with API level. */
      versionCode 30000 + android.defaultConfig.versionCode
      versionNameSuffix "-minApi24"
    }

    minApi23 {
      dimension "api"
      minSdkVersion '23'
      versionCode 20000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi23"
    }

    minApi21 {
      dimension "api"
      minSdkVersion '21'
      versionCode 10000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi21"
    }
  }
}
           

[Filter variants]

您可以使用子產品的 build.gradle 檔案中的

variantFilter

代碼塊過濾建構變體,将您不想要的變體過濾掉。以下示例代碼将訓示 Gradle

不建構任何可以将 minApi21 與 demo 産品風味組合的變體

android {
  variantFilter { variant ->
      def names = variant.flavors*.name //精準比對時使用【variant.buildType.name == "<buildType>"】
      if (names.contains("minApi21") && names.contains("demo")) {
          //具體的邏輯
      }
  }
}
           
android {
  buildTypes {...}
  flavorDimensions "api", "mode"
  productFlavors {
    demo {...}
    full {...}
    minApi24 {...}
    minApi23 {...}
    minApi21 {...}
  }

  variantFilter { variant ->
      def names = variant.flavors*.name
      // To check for a certain build type, use 【variant.buildType.name == "<buildType>"】
      if (names.contains("minApi21") && names.contains("demo")) {
          setIgnore(true)  // Gradle ignores any variants that satisfy滿足 the conditions above.
      }
  }
}
           

[Test your app]

要詳細了解如何運作本地和內建單元測試,請閱讀測試應用。

[Configure lint options]

您可以使用子產品級 build.gradle 檔案中的

lintOptions

代碼塊配置特定的 lint 選項。要詳細了解如何為您的 Android 項目使用 lint,請閱讀使用 Lint 改進您的代碼。

android {
  lintOptions {
    disable 'TypographyFractions','TypographyQuotes'
    enable 'RtlHardcoded', 'RtlCompat', 'RtlEnabled'
    check 'NewApi', 'InlinedApi'
    quiet true
    abortOnError false
    ignoreWarnings true
  }
}
           
android {
  lintOptions {
    disable 'TypographyFractions','TypographyQuotes'  // Turns off checks for the issue IDs you specify.
    enable 'RtlHardcoded', 'RtlCompat', 'RtlEnabled' // These checks are in addition to the default lint checks.
/** To enable checks for only a subset of issue IDs and ignore all others, list the issue IDs with the 'check' property instead. This property overrides any issue IDs you enable or disable using the properties above. */
    check 'NewApi', 'InlinedApi'
    quiet true  // If set to true, turns off analysis progress reporting by lint.
    abortOnError false // if set to true (default), stops the build if errors are found.
    ignoreWarnings true // if true, only report errors.
  }
}
           

[Configure instrumentation manifest settings]

在 Gradle 建構您的測試 APK 時,它會自動生成 AndroidManifest.xml 檔案并為其配置

<instrumentation>

節點。您可以在 測試源集 中建立另一個 manifest 檔案或者配置您的子產品級 build.gradle 檔案,通過這兩種方式更改此節點的一些設定,如以下代碼示例中所示。

android {
  defaultConfig {
    testApplicationId "com.test.foo"
    testInstrumentationRunner "android.test.InstrumentationTestRunner"
    testFunctionalTest true
  }
}
           
android {
  defaultConfig {
    testApplicationId "com.test.foo"  // Specifies the application ID for the test APK.
    testInstrumentationRunner "android.test.InstrumentationTestRunner" // fully-qualified class name
    // If set to 'true', enables the instrumentation class to start and stop profiling.
    // If set to false (default), profiling occurs the entire time the instrumentation class is running.
    testHandleProfiling true
    // If set to 'true', indicates that the Android system should run the instrumentation class as a functional test. 
    testFunctionalTest true //The default value is 'false'
  }
}
           

[Change the test build type]

預設情況下,所有測試均針對調試建構類型運作。您可以利用子產品級 build.gradle 檔案中的

testBuildType

屬性将其更改為其他建構類型。例如,如果您想針對“staging”建構類型運作測試,請按下面這段代碼中所示對該檔案進行編輯。

android {
    testBuildType "staging"
}
           

[Configure Gradle test options]

要指定可以更改 Gradle 運作所有測試方式的選項,請配置子產品級 build.gradle 中的

testOptions

代碼塊。

android {
  testOptions {
    // '$rootDir' sets the path relative to the root directory of the current project.
    reportDir "$rootDir/test-reports" //預設在 project/module_name/build/outputs/reports/
    resultsDir "$rootDir/test-results" //預設在 project/module_name/build/outputs/test-results/
  }
}
           

要僅為本地單元測試指定選項,請配置

testOptions.unitTests

android {
  testOptions {
    unitTests {
/** By default, local unit tests throw an exception any time the code you are testing tries to access Android platform APIs (unless you mock嘲笑、藐視、不尊重 Android dependencies yourself or with a testing framework like Mockito). However, you can enable the following property so that the test returns either null or zero when accessing platform APIs, rather than throwing an exception. */
      returnDefaultValues true

      all { // controlling how Gradle executes local unit tests.
        jvmArgs '-XX:MaxPermSize=256m' // Sets JVM argument(s) for the test JVM(s).
        if (it.name == 'testDebugUnitTest') {  // You can also check the task name to apply options to only the tests you specify.
          systemProperty 'debug', 'true'
        }
      }
    }
  }
}
           

[Optimize your build]

本部分将介紹一些有助于加快您的完整建構和增量建構速度的配置。

[Shrink your code]

Android Studio 使用 ProGuard 來壓縮代碼。對于新項目,Android Studio 将使用

Android_SDK/tools/proguard/

下的預設設定檔案

proguard-android.txt

。要想進一步壓縮代碼,請嘗試使用位于同一位置的

proguard-android-optimize.txt

檔案。

android {
  buildTypes {
    release {
      minifyEnabled true //預設為false
      proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' //預設配置
    }
  }
}
           

要添加特定于每個建構變體的 ProGuard 規則,請為每個風味配置其他

proguardFiles

屬性。例如,以下示例會将 flavor2-rules.pro 添加到“flavor2”中。現在,釋出版本“flavor2”使用所有三個 ProGuard 規則,因為還應用了來自 release 代碼塊的規則。

android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
        }
    }
    productFlavors {
        flavor1 {
        }
        flavor2 {
            proguardFile 'flavor2-rules.pro'
        }
    }
}
           

[Enable code shrinking with Instant Run]

要通過 Instant Run 啟用代碼壓縮,隻需将

useProguard

設為 false(并保持 minifyEnabled 設為 true)。這将使用實驗性代碼壓縮器,它不會對您的代碼進行混淆處理或優化(是以,您應當僅為 debug 建構類型啟用此壓縮器)。

android {
    buildTypes {
        debug {
            minifyEnabled true
            useProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
           

[Configure dex Options]

在 Gradle 将您的代碼編譯到 DEX 檔案中時,使用以下屬性可以縮短建構時間。

android {
  dexOptions {
    maxProcessCount 8 // Sets the maximum number of DEX processes that can be started concurrently.
    javaMaxHeapSize "2g" // Sets the maximum memory allocation pool size for the dex operation.
    preDexLibraries true // Enables Gradle to pre-dex library dependencies.
  }
}
           

[Publish your app]

要詳細了解如何将使用的應用釋出到 Google Play,請閱讀釋出您的應用。

[Sign your app]

盡管 Android Studio 提供了一種從界面為釋出建構配置簽署的簡單方式,您仍然可以手動配置子產品的 build.gradle 檔案中的

signingConfigs

代碼塊:

android {
    defaultConfig {...}
    signingConfigs {
        release {
            storeFile file("myreleasekey.keystore")
            storePassword "password"
            keyAlias "MyReleaseKey"
            keyPassword "password"
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}
           

[Remove private signing information from your project]

預設情況下,簽署配置将以純文字形式記錄到子產品的 build.gradle 檔案中。如果您正在與某個團隊合作或者參與一個開放源代碼項目,可以執行以下步驟,将此敏感資訊移出建構檔案。

def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(rootProject.file("keystore.properties"))) //加載配置檔案

android {
  signingConfigs {
    config {
      keyAlias keystoreProperties['keyAlias']
      keyPassword keystoreProperties['keyPassword']
      storeFile file(keystoreProperties['storeFile'])
      storePassword keystoreProperties['storePassword']
    }
  }
}
           

1、在項目的根目錄下建立一個名為

keystore.properties

的檔案,并包含以下資訊:

storePassword=myStorePassword
keyPassword=myKeyPassword
keyAlias=myKeyAlias
storeFile=myStoreFileLocation
           

2、在您的 build.gradle 檔案中,按以下步驟操作來加載 keystore.properties 檔案(必須在 android 代碼塊之前):

def keystorePropertiesFile = rootProject.file("keystore.properties") // Creates and initializes a variable to the keystore.properties file.
def keystoreProperties = new Properties() // Initializes a new Properties() object
keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) // Loads the keystore.properties file into the Properties object.

android { ... }
           

3、輸入存儲在 keystoreProperties 對象中的簽署資訊:

android {
  signingConfigs {
    config {
      keyAlias keystoreProperties['keyAlias']
      keyPassword keystoreProperties['keyPassword']
      storeFile file(keystoreProperties['storeFile'])
      storePassword keystoreProperties['storePassword']
    }
  }
}
           

要詳細了解應用簽署,請閱讀 簽署您的應用。

[Simplify app development]

下面的提示有助于簡化您的 Android 應用開發。

[Share custom fields and resource values with your app's code]

在建構時,Gradle 将生成

BuildConfig

類,以便您的應用代碼可以檢查與目前建構有關的資訊。您也可以使用

buildConfigField()

函數,将自定義字段添加到 Gradle 建構配置檔案的 BuildConfig 類中,然後在應用的運作時代碼中通路這些值。同樣,您也可以使用

resValue()

添加應用資源值。

android {
  buildTypes {
    release {
      buildConfigField("String", "BUILD_TIME", "\"${minutesSinceEpoch}\"")
      resValue("string", "build_time", "${minutesSinceEpoch}")
    }
  }
}
           
android {
  buildTypes {
    release {
      // These values are defined only for the release build, which is typically典型的 used for 【full builds】 and 【continuous builds】.
      buildConfigField("String", "BUILD_TIME", "\"${minutesSinceEpoch}\"")
      resValue("string", "build_time", "${minutesSinceEpoch}")
    }
    debug {
      // Use static values for incremental builds to ensure that resource files and BuildConfig aren't rebuilt重建 with each run.
      // If they were dynamic, they would prevent阻止 certain某一、某些 benefits利益、福利、優勢 of Instant Run as well as Gradle UP-TO-DATE checks.
      buildConfigField("String", "BUILD_TIME", "\"0\"")
      resValue("string", "build_time", "0")
    }
  }
}
           

在您的應用代碼中,您可以通路以下屬性:

Log.i(TAG, BuildConfig.BUILD_TIME);
Log.i(TAG, getString(R.string.build_time));
           

[Share properties with the manifest]

某些情況下,您可能需要同時在 manifest 和代碼中聲明相同屬性(例如,在為

FileProvider

聲明機構時)。如以下示例中所示,請在子產品的 build.gradle 檔案中定義一個屬性并使其對 manifest 和代碼均可用,而不必在多個位置更新相同的屬性以反映更改。要了解詳情,請閱讀 将建構變量注入 Manifest。

android {
  defaultConfig {
      manifestPlaceholders = [
          filesAuthority: "${applicationId}.files",
          app_logo         : "@drawable/icon",
          app_channel_value: "小米應用市場",
      ]
  }
}
           
android:authorities="${filesAuthority}"
           
android {
  defaultConfig {
      def filesAuthorityValue = applicationId + ".files" // Creates a property for the FileProvider authority.

      // Creates a placeholder property to use in the manifest.
      manifestPlaceholders = [filesAuthority: filesAuthorityValue,
                                    app_logo         : "@drawable/icon",
                                    app_channel_value: "小米應用市場",
      ]

      // Adds a new field for the authority to the BuildConfig class.
      buildConfigField("String", "FILES_AUTHORITY", "\"${filesAuthorityValue}\"")
      buildConfigField "String", "BASE_URL", '"http://120.com/"'
      buildConfigField "int", "countryCode", "20094"
  }
}
           

在您的 manifest 中,通路以下占位符:

<manifest>
  <application>
    <provider
      android:name="android.support.v4.content.FileProvider"
      android:authorities="${filesAuthority}"
      android:exported="false"
      android:grantUriPermissions="true"/>
  </application>
</manifest>
           
以上内容上次更新日期:五月 8, 2018

2019-5-12

本文來自部落格園,作者:白乾濤,轉載請注明原文連結:https://www.cnblogs.com/baiqiantao/p/10852853.html

繼續閱讀