Как заменить строки ресурсов на Android Gradle
Я создал новое приложение с gradle в Android Studio, и теперь мне нужно сделать около 10 версий с разными именами пакетов и значениями в ресурсах. Я сделал специальные вкусы, как в примере, и хочу заменить некоторые строки в этих пользовательских вкусах на пользовательские значения. Я нашел такой пример:
filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: ['version': '2.2'])
Но я не знаю, куда его поместить. Как я понимаю, мне нужно поставить его в отдельную задачу, но как сделать эту задачу вызванной IDE?
Также мне нужно заменить несколько переменных внутри классов Java и Autodesk Content Provider, возможно, мне нужно сделать это, скопировав файлы в папку flavor1 и позволить gradle объединить его, но это похоже на неправильное решение для хранения многих копий файлы с разницей в одной строке... Может быть, мне нужно какое-то другое решение для всего этого?
Вот build.gradle:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.4.2'
}
}
apply plugin: 'android'
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile project(':JazzyListView')
compile project(':ABS')
compile project(':Volley')
}
android {
compileSdkVersion 17
buildToolsVersion "17.0.0"
defaultConfig {
versionCode 5
versionName "3.0"
minSdkVersion 8
targetSdkVersion 17
}
sourceSets {
main {
manifest.srcFile 'src/main/AndroidManifest.xml'
java.srcDirs = ['src/main/java']
res.srcDirs = ['src/main/res']
}
}
productFlavors {
flavor1 {
packageName "com.example.flavor1"
}
flavor2 {
packageName "com.example.flavor2"
}
}
}
Ответы
Ответ 1
У меня была аналогичная проблема. Я хотел добавить номер сборки Jenkins к строкам, которые сливаются из strings.xml. Здесь мое решение с Android Gradle плагин 0.12. +.
// Insert the build number into strings.xml
android.applicationVariants.all{ variant ->
variant.mergeResources.doLast{
ext.env = System.getenv()
def buildNumber = env.BUILD_NUMBER
if (buildNumber != null) {
File valuesFile = file("${buildDir}/intermediates/res/${variant.dirName}/values/values.xml")
println("Replacing revision number in " + valuesFile)
println("Build number = " + buildNumber)
String content = valuesFile.getText('UTF-8')
content = content.replaceAll(/devBuild/, buildNumber)
valuesFile.write(content, 'UTF-8')
}
}
}
Возможно, вы захотите подключиться к другой задаче Gradle в зависимости от того, что вы хотите сделать. Взгляните на задачи, которые являются частью сборки Android, чтобы понять это.
http://tools.android.com/tech-docs/new-build-system/user-guide
UPDATE. В какой-то момент плагин Android Gradle изменил способ итерации по ключевому слову вариантов приложений от каждого к каждому. Мой ответ был обновлен, чтобы отразить изменения, но попробуйте переключиться на каждый, если этот код ничего не печатает на консоли.
Ответ 2
Я пытался получить аналогичную функциональность, такую как фильтрация ресурсов Maven.
Это то, что я придумал. Мое решение может использовать некоторые изменения, чтобы быть более надежными (т.е. Вытаскивать из файла свойств и т.д.).
В моем примере показано, как заменить одно значение, которое все, что мне нужно. Переменные следуют за соглашением ${some.property}
. Это решение также работает с продуктами, которые имеют свои собственные файлы ресурсов.
import org.apache.tools.ant.filters.*
...
android.applicationVariants.all{ variant ->
// Perform resource filtering
variant.mergeResources.doLast {
filterResources(variant)
}
}
def filterResources(buildVariant) {
//Setup temp directory to filter the resources
File resFiltered = file("${buildDir}/res/all/filtered/${buildVariant.dirName}")
if(resFiltered.exists()){
resFiltered.delete()
}
//Copy and filter the resources.
copy {
from(buildVariant.processResources.resDir) {
include '**/*.xml'
//Could be improved upon to pull from a properties file, etc.
ant.properties['app.version'] = project.version
filter(ExpandProperties, project: ant.project)
}
from(buildVariant.processResources.resDir) {
exclude '**/*.xml'
}
into resFiltered
}
//Delete all the original resource files
file(buildVariant.processResources.resDir).deleteDir()
//Replace with the filtered ones.
resFiltered.renameTo(file(buildVariant.processResources.resDir))
//Delete the original 'filtered' directory
file( "${buildDir}/res/all/filtered").deleteDir()
}
Пример в strings.xml
...
<string name="app_version">${app.version}</string>
...
Ответ 3
В папке "src" создайте папки "flavor1" и "flavor2" с той же иерархией, что и ваша "основная" папка. Если у вас есть strings.xml в ваших основных /res/values, вы можете сделать это в flavor1/res/values, а также иметь там значения замены. Он может показывать ошибки в среде IDE, но он все равно должен строиться и запускаться.
Ответ 4
Эти ссылки могут быть полезны:
И мое определение фильтра с использованием регулярного выражения для замены:
from('res/') {
include '**/*.xml'
filter {
line -> line.replaceAll(/YOUR_REGEX_TO_REPLACE_SOMETHING/, 'REPLACED_RESULT_EXPRESSION')
}
}
into 'build/path/to/your/filtered/resources/'