Today I Learned
내가 작성한 코드를
apk(android package),aar(android archive)로 만드는 과정
Project 로 보기

Android 로 보기

build.gradle (Project: MyAppliation)
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.0'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
build.gradle (Module: app)
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.example.ragu.myapplication"
minSdkVersion 19
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.0'
testCompile 'junit:junit:4.12'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
}
gradle.settings
include ':app'
gradle.properties
systemProp.http.proxyHost=70.10.15.10
systemProp.http.proxyPort=8080
systemProp.http.nonProxyHosts=70.*|localhost
systemProp.https.proxyHost=70.10.15.10
systemProp.https.proxyPort=8080
systemProp.https.nonProxyHosts=70.*|localhost
buildscript {
...
dependencies {
classpath 'com.android.tools.build:gradle:2.3.0'
}
}
buildscript {
repositories {
jcenter()
}
dependencies {...}
}
allprojects {
repositories {
jcenter()
}
}
| 저장소 이름 | 운영사 | 속도 | 규모 | 안드로이드 스튜디오 기본 저장소 | 사용자 친화도 |
|---|---|---|---|---|---|
| jcenter | bintray.com | 빠름(CDN 사용) | 더큼 | 현재 | 높음(쉬움) |
| manveCentral | sonatype.org | 덜빠름 | 큼 | 과거 | 낮음(어려움) |
bintray.com은
jcenter에서maven central으로 배포하는 기능을 제공한다.
로컬에 있는 메이븐 캐시 사용
repositories {
mavenLocal()
}
로컬 파일 시스템에 있는 라이브러리 파일 참조
repositories {
flatDir {
dirs 'lib'
}
}
기타 메이븐 저장소 url을 직접 지정
repositories {
maven {
url 'http://repo.mycompony.com/maven'
}
}
비밀번호가 걸려있는 저장소
repositories {
maven {
credentials {
username 'username'
password 'password'
}
url 'http://repo.mycompony.com/maven'
}
}
gradle.build(Module: app)
apply plugin: 'com.android.application'
...
gradle.build(Module: app)
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.example.ragu.myapplication"
minSdkVersion 19
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
...
}
| 속성 이름 | 내용 |
|---|---|
| compileSdkVersion | 컴파일에 사용할 SDK 버전 |
| minSdkVersion | 지원하는 최소 SDK 버전으로, SDK 버전이 이 값보다 낮은 기기에서는 해당 어플리케이션을 검색할 수 없음. |
| targetSdkVersion | 어플리케이션이 의도하는 목적 SDK 버전. 최신버전보다 낮으면 안드로이드 스튜디오에서 경고 표시됨. |
gradle.build(Module: app)
android {
...
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
명시하지 않으면 기본 설정이 적용됨.
gradle.build(Module: app)
android {...}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.0'
testCompile 'junit:junit:4.12'
}
실무에서는 외부에 공개된 라이브러리가 아닌 특정 회사에만 공개된 private 라이브러리를 참조하는 경우에만 사용한다. by 안드로이드를 위한 Gradle(저자: 유동환)
그래 위에 설명들은 알았다 치고, 어떻게 빌드하는거지?


뭔가 내가 작성한게 적용이 안된것만 같은 느낌…
안드로이드 Gradle 플러그인을 이용

원하는 Task 더블 클릭
쉘에서 직접 Gradle Task 실행하기
> ./gradlew clean
> ./gradlew test
> ./gradlew clean assembleDebug
> ./gradlew assemble
> ./gradlew build


뭘 좋아하는지 몰라서 다 준비해봤어
특정 Task를 제외하고 빌드하는 방법
> ./gradlew build -x check
사전적 의미 -> 보푸라기
의심스럽거나, 에러를 발생하기 쉬운 코드에 flag 를 달아 놓는 것
Android Lint에서 검사하는 항목 중 대표적인 부분
을 빌드 시점에 알려준다.

마켓별로 다른 package, version code, version name, sdk version 등을 따로 관리하고 싶은 경우 Gradle 의 flavor 기능을 이용하면 쉽게 적용을 할 수 있다.
build.gradle(module: app)
android {
...
defaultConfig {...}
buildTypes {...}
productFlavors {
demo {
applicationId "io.github.ragubyun.myapplication.demo"
versionName "1.0-demo"
}
full {
applicationId "io.github.ragubyun.myapplication.full"
versionName "1.0-full"
}
}
sourceSets {
demo {
java.srcDirs = ['src/main/java', 'src/demo/java']
res.srcDirs = ['src/main/res', 'src/demo/res']
}
full {
java.srcDirs = ['src/main/java', 'src/full/java']
res.srcDirs = ['src/main/res', 'src/full/res']
}
}
}
프로젝트 폴더 구조

Build Variants

applicationId를 다르게 가져가므로 사실상 완전히 별개의 앱이라고 볼 수 있다.
중요! Android Library Project는
productFlavor를 지원하지 않는다.
build.gradle(Module: app)
android {
...
productFlavors {
internal {
buildConfigField 'String', 'proxyHost', '"' + PROXY_HOST + '"'
buildConfigField 'int', 'proxyPort', PROXY_PORT
buildConfigField 'String', 'certKeystoreDigest', '"' + CERT_KEYSTORE_DIGEST + '"'
}
production {
buildConfigField 'String', 'proxyHost', 'null'
buildConfigField 'int', 'proxyPort', '0'
buildConfigField 'String', 'certKeystoreDigest', 'null'
}
}
}
buildConfigField 'type', 'name', 'value'
buildConfigField(T type, String name, String value)
gradle.properties
PROXY_HOST=70.10.15.10
PROXY_PORT=8080
CERT_KEYSTORE_DIGEST=AAAAAgAAABS.......nBLz3uzNP05V3c7
Build Variants

NetModules.java
@Provides
@Singleton
public OkHttpClient httpClient() {
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.MINUTES)
.readTimeout(1, TimeUnit.MINUTES)
.writeTimeout(1, TimeUnit.MINUTES);
if (isNotUnitTest() && BuildConfig.proxyHost != null) {
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(BuildConfig.proxyHost, BuildConfig.proxyPort));
clientBuilder.proxy(proxy);
try {
byte[] keyStoreBytes = Base64.decode(BuildConfig.certKeystoreDigest, Base64.DEFAULT);
ByteArrayInputStream keyStore = new ByteArrayInputStream(keyStoreBytes);
KeyStore keystore = KeyStore.getInstance("BKS");
keystore.load(keyStore, "changeit".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keystore, "changeit".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
tmf.init(keystore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
clientBuilder.sslSocketFactory(socketFactory);
} catch (Exception e) {
e.printStackTrace();
}
}
return clientBuilder.build();
}
Build Type x Product Flavor
gradle.build(Project: MyApplication)
buildscript {...}
allprojects {...}
task clean(type: Delete) {
delete rootProject.buildDir
}
task sayHello(group: 'custom',
description: 'This task says Hello',
dependsOn: clean) << {
println 'Hello Gradle!'
}


이전 안드로이드 버전을 사용하고 있는 기기에서 새로운 API를 사용 할수 있도록 도와주는 호환성 라이브러리이며 새로운 안드로이드 버전이 나올때 마다 업데이트 된다. 주요 호환성 라이브러리로는 V4및 V7-AppCompat이 있다.
support-v4
안드로이드 API4부터 사용이 가능한 라이브러리로 API 11에서 소개된 Fragment와 Loader등 주요 클래스의 구현을 지원하며 ViewPager, DrawerLayout등 포함 되어 있다.
appcompat-v7
V4를 이용하여 확장한 라이브러리로 단순히 액션바(API 11), 툴바(API 21)등을 지원한다.
안드로이드 스튜디오의 새로운 프로젝트 템플릿을 보면 support-v4와 appcompat-v7을 기본적으로 포함시켜 개발자로 하여금 의존할 수 있도록 노력하고있다. 즉, 서포트 라이브러리가 필요 하지 않는 경우라도 일반적으로 사용하기를 구글에서는 권하고 있다. by 꿈꾸는 개발자의 로그 블로그

책 소개를 가장한 노트북 자랑질…



끝