Dependency, Android Libraries and Multi-project setup
-
external library jar 를 사용하려면 compile configuration 을 사용하면 된다.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar']) // api 와 implementation 으로 바뀌었다.
}
android {
...
}
-
compile 은 main app 을 compile 한다.
compile 되는 모든 것은 compile classpath 로 잡히고, final APK 에 포함이 된다.
다음과 같은 compile configuration 을 추가할 수 있고,
buildType 을 추가하면 자동으로 compile 이 추가된다.
androidTestCompile
debugCompile
releaseCompile
// <buildtype>Compile
-
Gradle 은 Maven 과 Ivy repository 에서 artifact 를 끌어올 수 있다.
repository 를 명시하고, dependency 에 artifact 를 정의해주면 된다.
repositories {
jcenter()
}
dependencies {
compile 'com.google.guava:guava:18.0’ // gradle 은 transitive 하기에, lib 에서 다른 lib 참조하면 모두 긁어온다.
}
android {
...
}
-
다른 gradle project 에 의존하여 multi-project setup 이 가능하다.
root project 의 sub folder 로 만들어 진행 가능하다.
MyProject/
+ app/
+ libraries/
+ lib1/
+ lib2/
위에는 3개의 project 가 있다.
각각의 project 는 각각의 build.gradle 을 가져야 한다.
multi project 의 경우 settings.gradle 을 root 에 위치시키고, project 들을 명시해주어야 한다.
include ':app', ':libraries:lib1', ':libraries:lib2'
:app project 가 lib1 에 의존한다면 dependency 에 추가해주어야 한다. (local 참조)
dependencies {
compile project(':libraries:lib1')
}
-
Java Project 의 경우 위와 같은 설정을 하면 jar output 을 잘 이용한다.
그러나 android 와 관련된 library 의 경우에는 android library project 로 만들어주어야 한다.
project 의 build.gradle 에 아래 plugin 을 적용해주면 된다.
apply plugin: 'com.android.library'
library project 의 output 은 jar 가 아닌 aar 이다. ( Android Archive 의 약자 )
이는 code 와 resource 를 모두 조합한 녀석이다.
-
기본적으로 library 는 release build 만 제공한다.
아래와 같이 다른 형태의 variant 를 제공할 수 있다.
( 필요가 참여한 프로젝트들은 buildTypes 를 library build.gradle 에도 적용 가능했다. 아마 버전업 하면서 통일성을 갖추었나보다. )
android {
defaultPublishConfig "debug"
}
android {
defaultPublishConfig “flavor1Debug” // flavor 를 사용하는 경우
}
-
Library 는 default 외에는 기본으로 variant 가 enable 되어 있지 않아 아래와 같이 써주어야 한다.
android {
publishNonDefault true
}
-
다음과 같이 조건에 따라 dependency 를 걸 수 있다.
dependencies {
flavor1Compile project(path: ':lib1', configuration: 'flavor1Release')
flavor2Compile project(path: ':lib1', configuration: 'flavor2Release')
}
-
testing 부분은 생략…
-
특정 variant 에 lint 를 돌릴 수 있다.
android {
lintOptions {
// turn off checking the given issue id's
disable 'TypographyFractions','TypographyQuotes'
// turn on the given issue id's
enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
// check *only* the given issue id's
check 'NewApi', 'InlinedApi'
}
}
Build Variant
-
한 app 에 대해 다른 버전들을 만드는 것이 build system 의 목적 중 하나.
예를 들면 한 소스로..
free/demo/pro version 제작
다른 형태로 package 되어 multi-apk 로 만든다.
둘의 조합
-
product flavor 는 customized 된 build 를 말한다.
한 project 는 여러개의 flavor 를 가질 수 있다.
android {
...
defaultConfig {
minSdkVersion 8
versionCode 10
}
productFlavors {
flavor1 { // android.defaultConfig object 이다.
applicationId "com.example.flavor1"
versionCode 20
}
flavor2 {
applicationId "com.example.flavor2"
minSdkVersion 14
}
}
}
flavor 이름은 build type 과 conflict 나면 안 된다.
물론 androidTest 나 test 등의 이름이 되어서는 안된다.
-
Build Type + Product Flavor 가 Build Variant 이다.
Flavor 가 없는 경우에는 Build Type 이 홀로 Build Variant 가 된다.
-
Build Type configuration 은 다른 config 의 overlay 가 된다.
즉 Build Type Config > Flavor Config
-
Build Type 과 마찬가지로 Product Flavor 도 기본 sourceSet 을 만든다.
android.sourceSets.flavor1
Location src/flavor1/
android.sourceSets.flavor2
Location src/flavor2/
이는 Build Type 의 sourceSet 과 결합하여 하나의 APK 를 만드는 데 사용된다.
모든 source code ( src/*/java ) 가 single output 을 만드는 데 사용된다.
Manifest 가 single manifest 로 merge 한다.
모든 resource 는 overlay 된다. Build Type > Product Flavor > main 순의 우선순위를 갖는다.
각각의 Build Variant 는 각각의 R class 를 갖는다. variant 간 share 되지 않는다.
-
Flavor 역시 compile 옵션이 될 수 있다.
dependencies {
flavor1Compile "..."
}
-
BuildType 과 Flavor 가 결합된 형태도 compile 옵션이 될 수 있고, 이에 대한 SourceSet 도 가질 수 있다.
android.sourceSets.flavor1Debug
Location src/flavor1Debug/
android.sourceSets.flavor1Release
Location src/flavor1Release/
-
다음과 같이 flavorDimension 을 정의하면 flavor 간의 hierarchy 를 만드는 것도 가능하다.
android {
...
flavorDimensions "abi", “version” // 순서가 hierarchy 를 갖는다!!!
productFlavors {
freeapp {
dimension "version"
...
}
paidapp {
dimension "version"
...
}
arm {
dimension "abi"
...
}
mips {
dimension "abi"
...
}
x86 {
dimension "abi"
...
}
}
}
위와 같이 정의하면 아래와 같은 variant 가 나온다.
x86-freeapp-debug
x86-freeapp-release
arm-freeapp-debug
arm-freeapp-release
mips-freeapp-debug
mips-freeapp-release
x86-paidapp-debug
x86-paidapp-release
arm-paidapp-debug
arm-paidapp-release
mips-paidapp-debug
mips-paidapp-release
flavorDimentsions array 에서 version 이 먼저 define 되었기 때문에 abi-version-buildType 의 순으로 생기는 것이다.
-
compile time 에 Android Studio 는 상수들을 담고 있는 BuildConfig 라는 것을 자동 생성한다.
이 상수들을 이용해 무언가를 할 수 있다.
private void javaCode() {
if (BuildConfig.FLAVOR.equals("paidapp")) {
doIt();
} else {
showOnlyInPaidAppDialog();
}
}
-
BuildConfig 가 담을 수 있는 녀석들은..
boolean DEBUG
int VERSION_CODE
String VERSION_NAME
String APPLICATION_ID
String BUILD_TYPE // release
String FLAVOR // paidapp
만약 flavor dimension 을 이용한다면 다음것들이 추가로 생성된다.
String FLAVOR // “armFreeapp”
String FLAVOR_abi // “arm”
String FLAVOR_version // “freeapp"
-
dimension 과 flavor 를 사용하다보면, 사용하고 싶지 않은 variant 값들이 있을 수 있다. ( 자동조합되므로 )
이는 variantFilter 로 제거할 수 있다.
android {
productFlavors {
realData
fakeData
}
variantFilter { variant ->
def names = variant.flavors*.name
if (names.contains("fakeData") && variant.buildType.name == "release") {
variant.ignore = true
}
}
}
위와 같이 하면 다음의 3개만 생성된다.
realDataDebug
realDataRelease
fakeDataDebug
// fakeDataRelease 가 생성되지 않는다.
Advanced Build Customization
-
proguard 를 돌리기 위해서는 아래와 같이 minifyEnabled 와 proguardFile property 를 이용하면 된다.
android {
buildTypes {
release {
minifyEnabled true
proguardFile getDefaultProguardFile('proguard-android.txt')
}
}
productFlavors {
flavor1 {
}
flavor2 {
proguardFile 'some-other-rules.txt'
}
}
}
proguard 에는 2가지 rule file 이 있다.
proguard-android.txt
proguard-android-optimize.txt
getDefaultProguardFile() 은 파일들의 full path 를 가져온다.
-
사용하지 않는 res shrink 도 가능하다.
-
기본 java project 는 output 을 만들기 위한 task 들이 있다.
그 중 하나인 classes task 는 java source code 를 compile 하는 데 쓰인다.
build.gradle 에서는 project.tasks.classes 를 이용해 쉽게 접근 가능하다.
-
Android 의 경우 task 의 갯수가 훨씬 많고, Build Type 과 Product Flavor 에 이름이 depdent 하기 때문에 복잡하다.
그래서 android 는 다음을 제공한다.
applicationVariants (only for the app plugin)
libraryVariants (only for the library plugin)
testVariants (for both plugins)
이 녀석들은 DomainObjectCollection 을 retrun 한다.
이 녀석이 갖는 property table 은 최상단의 link 참조..
-
compileOptions 를 이용해 language level 도 설정 할 수 있다.
기본값은 compileSdkVersion 에 의해 선택된다.
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_6
targetCompatibility JavaVersion.VERSION_1_6
}
}
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
Overview of Android Memory Management ( 안드로이드의 메모리 관리 ) (0) | 2018.10.09 |
---|---|
[android] Background Optimization ( 백그라운드 최적화 ) (0) | 2018.10.08 |
[android] Gradle Tutorial #1 (0) | 2018.10.04 |
[정리] 안드로이드 전문가 되는 법 (0) | 2018.10.03 |
[android] Java8 을 사용해보자! (0) | 2018.10.02 |
댓글