Прошло уже достаточно много времени с момента презентации Android Studio и наверняка у многих накопилось много знаний, нюансов и фишек, используемых часто в работе. Этим и хочется поделиться. Я начну, а вы продолжите…
- SSD
- Наполнение лэйаута тестовыми данными
- Автоинкремент версии и изменение имени билда
- Создание различных вариантов сборки
- Пипетка
- Просмотр истории блока кода
SSD
Сборщик Gradle собирает долго. Если на простом проекте время сборки занимает до 10 секунд, то на большом, со множеством модулей — до двух минут. С учётом того, что за день работы проект собирается десятки раз в день, выходит большая утечка времени и появляется раздражительность (комп иногда уходит в ANR, даже браузером невозможно пользоваться). Проблема решается просто —
Результаты моего тестирования SSD:
1. ANR винды пропали
2. Время сборки сложных проектов уменьшилось от максимум двух минут до максимум 20 секунд.
3. Покупка SSD позволяет безболезненно использовать genymotion в связке со студией.
Сравнение скоростей работы HDD(сверху) и SSD(снизу), подключенного через SATA 1:
Наполнение лэйаута тестовыми данными
Префикс «tools:» помимо линтовских функций позволяет наполнять лэйаут тестовым данными без последствий для приложения.
Возможны даже такие вещи:
android:visibility="gone”
tools:visibility="visible”
Более подробно здесь — tools.android.com/tips/layout-designtime-attributes.
Ознакомиться с дополнительными возможностями по использованию префикса «tools:» можно здесь — tools.android.com/tech-docs/tools-attributes.
Автоинкремент версии и изменение имени билда
Градл полностью автоматизирует сборку и позволяет собирать различные билды одним кликом. Ниже код из build.gradle, который позволяет не забыть поднять версию приложения и переименовывает билд с учётом версии и даты — appname-release_v50_2014-11-04
Пример:
Далее остаётся запустить команду release главного модуля проекта.
import java.util.regex.Pattern
android {
buildTypes {
debug {
applicationIdSuffix '.debug'
debuggable true
runProguard false
jniDebugBuild false
}
release {
signingConfig signingConfigs.release
applicationVariants. { variant ->
def file = variant.outputFile;
def newName = file.name.replace("release.apk", "release_v" + getVersionCode() + "_" + getDate() + ".apk");
variant.outputFile = new File(file.parent, newName)
}
runProguard true
proguardFile file("proguard.pro")
debuggable false
jniDebugBuild false
}
}
}
def getDate() {
def date = new Date()
def formattedDate = date.format('yyyy-MM-dd')
return formattedDate
}
def getVersionCode() {
println "getVersionCode"
def manifestFile = file("AndroidManifest.xml")
def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
def manifestText = manifestFile.getText()
def matcher = pattern.matcher(manifestText)
matcher.find()
def version = ++Integer.parseInt(matcher.group(1))
println sprintf("Returning version %d", version)
return version
}
task incrementVersionCode << {
println(":incrementVersionCode - Incrementing Version Code...")
def manifestFile = file("src/main/AndroidManifest.xml")
def patternVersionCode = Pattern.compile("versionCode=\"(\\d+)\"")
def manifestText = manifestFile.getText()
def matcherVersionCode = patternVersionCode.matcher(manifestText)
matcherVersionCode.find()
def mVersionCode = Integer.parseInt(matcherVersionCode.group(1))
def mNextVersionCode = mVersionCode + 1
def manifestContent = matcherVersionCode.replaceAll("versionCode=\"" + mNextVersionCode + "\"")
println(":incrementVersionCode - current versionCode=" + mVersionCode);
println(":incrementVersionCode - next versionCode=" + mNextVersionCode);
manifestFile.write(manifestContent)
}
task incrementVersionName << {
println(":incrementVersionName - Incrementing Version Name...")
def manifestFile = file("src/main/AndroidManifest.xml")
def patternVersionNumber = Pattern.compile("versionName=\"(\\d+)\\.(\\d+)\"")
def manifestText = manifestFile.getText()
def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
matcherVersionNumber.find()
def majorVersion = Integer.parseInt(matcherVersionNumber.group(1))
def minorVersion = Integer.parseInt(matcherVersionNumber.group(2))
def mVersionName = majorVersion + "." + minorVersion
def mNextVersionName = majorVersion + "." + (minorVersion + 1)
def manifestContent = matcherVersionNumber.replaceAll("versionName=\"" + mNextVersionName + "\"")
println(":incrementVersionName - current versionName=" + mVersionName);
println(":incrementVersionName - new versionName=" + mNextVersionName);
manifestFile.write(manifestContent)
}
task release << {
println(":release - Build and Version Increment")
}
task debug << {
println(":debug - Build")
}
incrementVersionName.mustRunAfter build
incrementVersionCode.mustRunAfter build
debug.dependsOn assembleDebug
release.dependsOn assembleRelease
release.dependsOn incrementVersionCode
release.dependsOn incrementVersionName
Далее остаётся запустить команду release главного модуля проекта.
Создание различных вариантов сборки
Думаю один из самых простых и популярных вариантов использование данной возможности это создание бесплатной и платной версии приложения или версии под релизный и тестовый сервер.
Ниже пример на данную тему
Пример:
Указываем варианты сборки — free и paid, и соответствующие параметры в build.gradle
В случае релизного и тестового сервера:
Затем создаём папки в src с соответствующими названиями. Получится следующая структура проекта:
В ресурсах указываем различающиеся данные. Например, различные ключи для google analytics, crittercism, google backup service и пр.
В коде делаем проверки на BuildConfig.PAID для реализации логики.
productFlavors {
free {
packageName "by.yegorov.communal"
buildConfigField "boolean", "PAID", "false"
}
paid {
packageName "yo.mobile.meters"
buildConfigField "boolean", "PAID", "true"
}
}
В случае релизного и тестового сервера:
productFlavors {
debugServer {
buildConfigField "String", "SERVER_PATH", "\"http://test.api.ru\""
}
releaseServer {
buildConfigField "String", "SERVER_PATH", "\"http://api.ru\""
}
}
Затем создаём папки в src с соответствующими названиями. Получится следующая структура проекта:
В ресурсах указываем различающиеся данные. Например, различные ключи для google analytics, crittercism, google backup service и пр.
В коде делаем проверки на BuildConfig.PAID для реализации логики.
Пипетка
Пипетка позволяет узнать код цвета с любой области на экране. Многие её просто не замечают и пользуются пэйнтом для того, чтобы узнать код цвета с картинки. Обратите внимание на левый верхний угол. Данная диаложка вызывается из colors.xml при клике по цвету.
Просмотр истории блока кода
Согласитесь, стандартная ситуация при работе в команде. Не знаю, как давно существует данное решение и есть ли оно в эклипсе, но вещь действительно полезная:
Всем спасибо! Жду ваших комментариев.
Only registered users can participate in poll. Log in, please.
Ваше отношение к Android Studio:
14.15% Не пробовал15
1.89% Пробовал, вернулся на Eclipse2
83.96% Попробовал и остался89
106 users voted. 17 users abstained.