sitelink1 | https://sikeeoh.github.io/2017/08/28/imp...-plugin-3/ |
---|---|
sitelink2 | |
sitelink3 |
하단의 내용을 요약하자면 build.gradle 에서 dependencies{} 내의 compile 명령어를 implementation 으로 바꿔주면 된다
그리고 왜 그렇게 해야하는지에 대해 알고싶다면 하단을 참고
나는 프로젝트에서 Android Gradle 플러그인 3.0을 사용하는 동안 compile
키워드가 Deprecated 되었고 새롭게 나온 implementation
과 api
를 위해 더 이상 compile
이 추후에 사용되지 않는 것으로 되었습니다.
위 두 가지 모두 예제를 통해 이해 해 보도록 하겠습니다.
샘플 어플(kotlin)은 여기있습니다.
라이브러리 모듈이 4개인 프로젝트를 가정 해 보겠습니다.
-
LibraryA
-
LibraryB
-
LibraryC
-
LibraryD
종속성(의존성) 트리는 다음과 같습니다.
모든 라이브러리 모듈 속에는 간단하게 작성 된 클래스 파일이 들어 있습니다.
LibraryD:
1
2
3
4
5
|
class ClassD {
fun tellMeAJoke(): String {
return "You are funny :D"
}
}
|
LibraryC:
1
2
3
4
5
|
class ClassC {
fun tellMeAJoke(): String {
return "You are funny :C"
}
}
|
LibraryB:
1
2
3
4
5
6
7
|
class ClassB {
val b = ClassD()
fun whereIsMyJoke(): String {
return b.tellMeAJoke()
}
}
|
LibraryA:
1
2
3
4
5
6
7
|
class ClassA {
val c = ClassC()
fun whereIsMyJoke(): String {
return c.tellMeAJoke()
}
}
|
위의 클래스 파일에서 LibraryA 및 LibraryB는 각각 LibraryC 그리고 LibraryD에 종속된다는 것을 알 수 있습니다.
LibraryA -> LibraryC
LibraryB -> LibraryD
따라서 build.gradle 파일에 이러한 종속성을 추가 해줘야 합니다.
Compile (2.0) or Api (3.0):
새로운 api
키워드는 이전 compile
키워드와 정확히 동일 합니다.
따라서 모든 compile
을 api
로 바꿔도 제대로 동작합니다.
이제 LibraryB에서 api
키워드를 사용하여 LibraryD의 의존성을 추가해 보겠습니다.
1
2
3
4
|
dependencies {
. . . .
api project(path: ':librayD')
}
|
마찬가지로 LibraryB 가 App module에 추가 됩니다.
1
2
3
4
|
dependencies {
. . . .
api project(path: ':libraryB')
}
|
이제는 LibraryB와 LibraryD 모두 App module에서 접근 할 수 있습니다.
sample App에서 두 라이브러리는 다음과 같이 접근 할 수 있습니다.
Implementation (3.0):
implementation
이 api
와 다른 점을 찾아야 할 시간입니다.
에제로 돌아가서 이번에는 implementation
키워드를 이용해서 LibraryC를 LibraryA로 가져와 봅시다.
1
2
3
4
|
dependencies {
. . . .
implementation project(path: ':libraryC')
}
|
App module도 똑같이
1
2
3
4
|
dependencies {
. . . .
implementation project(path: ':libraryA')
}
|
이제 App module에서 LibraryC에 접근하려고 시도하면 Android Studio에서 오류가 발생합니다.
이는 우리가 api
대신 implementation
을 사용한다면 App module에서 LibraryC에 직접 접근 할 수 없다는 것을 의미합니다.
그래서 implementation
을 사용함으로써 이득은 무엇일까요?
Implementation vs api:
첫 번째 시나리오에서 LibraryD는 api
를 사용하여 컴파일 됩니다.
LibraryD 내부에서 변경이 되면, Gradle은 LibraryD, LibraryB 및 LibraryB를 import하는 다른 모든 모듈(Module X)을 재 컴파일 해야 합니다.
첫번째 시나리오
그러나 두 번째 시나리오에서 LibraryC가 내부적으로 변경이 되면 Gradle은 LibraryC 및 LibraryA만 다시 컴파일 하면 됩니다.
App module 에서는 LibraryC를 직접 가져오지 못하고 또한 다른 클래스들은 LibraryC안에 구현 된 것들을 직접 사용 할 수 없으니까요.
두번째 시나리오
모듈을 많이 사용하는 프로젝트에서 작업하는 경우 (이 Fragmented Podcast 에서 어마무시한 빌드 시간 관련 이야기를 들었다)이 방법을 사용하면 빌드 프로세스의 속도가 크게 빨라질 수 있습니다.
샘플 프로젝트에서 이 작업을 시도했지만 약간의 개선이 있었습니다.
다음은 모든 시나리오에 대한 빌드 보고서 입니다.
Full Build:
Full Build
Change in LibraryD:
Change in LibraryD
Change in LibraryC:
Change in LibraryC
api 와 implementation에 대한 요약 설명
api
는 의존성에 추가하는 모듈이 의존하고 있는 다른 모듈 까지 접근이 가능합니다.
예 ) ModuleX 에서 LibraryA 를 api project(path: ':LibrayA')
로 의존성에 추가하면 ModuleX에서 LibraryC 클래스를 접근 할 수 있습니다.
implementation
는 의존성에 추가하는 모듈 외 추가하는 모듈이 의존하는 다른 모듈에는 접근이 불가능 합니다. 즉 위에 상황을 보자면 implementation project(path: ':LibraryA')
로 의존성에 추가하면 ModuleX에서 LibraryC 클래스에는 접근할 수 없습니다.
위에서 보았듯이 이로 인한 차이가 발생하여 빌드 속도의 개선이 있을 수 있습니다.
다시 한번 미흡한 글 읽어주셔서 감사합니다.
TL;DR(Too Long; Didn’t Read.):
모든
compile
을implementation
으로 바꾸고 프로젝트를 빌드해보세요.
만일 여러분이 성공적으로 잘 된다면 훌륭한 프로젝트 입니다.
그렇지 않으면 종속성이 있는지 찾아보고api
키워드를 사용하여 해당 라이브러리를 사용합시다.