๊นจ์•Œ ๊ฐœ๋… ๐Ÿ“‘/Android

[Android] Module ๊ตฌ์กฐ

interfacer_han 2025. 9. 15. 23:06

#1 Module?

#1-1 What

ํ•˜๋‚˜์˜ build.gradle์— ์ข…์†๋œ ์ฝ”๋“œ์˜ ๋ฒ”์œ„
= ๋นŒ๋“œ์˜ ์ตœ์†Œ ๋‹จ์œ„
= ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ตœ์†Œ ๋‹จ์œ„

์•ˆ๋“œ๋กœ์ด๋“œ ์•ฑ์€ Gradle๋กœ ๋นŒ๋“œ๋˜๊ณ , ๊ทธ ๋นŒ๋“œ์˜ ๋ช…์„ธ๋Š” build.gradle์— ์ ํžŒ๋‹ค. ๋ชจ๋“ˆ์ด build.gradle ํŒŒ์ผ์— ์ข…์†๋œ๋‹ค๋Š” ๋ง์€ ์ฆ‰ ๋ชจ๋“ˆ์€ "๋นŒ๋“œ์˜ ์ตœ์†Œ ๋‹จ์œ„"๋ผ๊ณ  ๋œป์ด ๋œ๋‹ค.

 

#1-2 Why

์™œ ์ด๋Ÿฐ ๋‹จ์œ„๋ฅผ ์“ธ๊นŒ? ๋‹ค์‹œ ๋งํ•ด, ์™œ "๋นŒ๋“œ์˜ ์ตœ์†Œ ๋‹จ์œ„"๋กœ์„œ ๋ชจ๋“ˆ์„ ์“ธ๊นŒ? ์ž์ฒด์ ์ธ ๋นŒ๋“œ ๊ตฌ์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค(= build.gradle ํŒŒ์ผ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค)๋Š” ๋ง์€, ์ž์ฒด์ ์œผ๋กœ ์ปดํŒŒ์ผํ•œ ๊ฒฐ๊ณผ๋ฌผ์„ ์ƒ์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์–˜๊ธฐ๋‹ค. ์ฆ‰, ์™ธ๋ถ€(ํƒ€์ธ)์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฐฐํฌ(= ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌํ™”)๊ฐ€ ๊ฐ€๋Šฅํ•œ ์ตœ์†Œ ๋‹จ์œ„๊ฐ€ ๋œ๋‹ค.

 

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์ด์•ผ๊ธฐ๋Š” ๊ธฐ๋Šฅ๋“ค์„ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ฐ๊ฐ ๋…๋ฆฝ์ ์œผ๋กœ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์–˜๊ธฐ๋‹ค. "์™œ ๊ฐ์ฒด์ง€ํ–ฅ์„ ์‚ฌ์šฉํ•˜๋Š”๊ฐ€? (์žฅ์ ์ด ๋ฌด์—‡์ธ๊ฐ€?)"๋ผ๋Š” ์งˆ๋ฌธ์— ๋Œ€ํ•œ ๋Œ€๋‹ต๊ณผ ๊ฐ™์€ ๋งฅ๋ฝ์ด๋‹ค.

 

๊ทธ๋ ‡๋‹ค๋ฉด '๊ฐ์ฒด์ง€ํ–ฅ์˜ ๋ฌธ์ œ์ (๋‹จ์ )'๋„ ๋น„์Šทํ•˜๊ฒŒ ๊ณต์œ ํ•  ๊ฒƒ์ด๋‹ค. ๋ณต์ˆ˜์˜ ๋ชจ๋“ˆ๋กœ ์ด๋ฃจ์–ด์ง„ ํ”„๋กœ์ ํŠธ๋Š” ๊ทธ ๋ชจ๋“ˆ๋“ค์˜ build.gradle์ด Java ๋ฒ„์ „, Kotlin ์˜ต์…˜, dependency ๋“ฑ์— ์ฐจ์ด๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค. ์ด ํŒŒํŽธํ™”๋Š” ์ž ์žฌ์ ์ธ ์—๋Ÿฌ๋ฅผ ์œ ๋ฐœํ•  ๊ฒƒ์ด๊ณ , ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๊ท€์ฐฎ์€ ์ž‘์—…์„ ํ•ด์•ผ๋  ์ˆ˜๋„ ์žˆ๋‹ค.

 

#1-3 package์™€์˜ ๋น„๊ต

์•ˆ๋“œ๋กœ์ด๋“œ ์•ฑ์˜ ์†Œ์Šค์ฝ”๋“œ๋Š” package๋ผ๋Š” ์ด๋ฆ„์˜ ํด๋”๋กœ ์นดํ…Œ๊ณ ๋ฆฌํ™”๋œ๋‹ค. package๋Š” ํŒŒ์ผ ํŠธ๋ฆฌ ์•ˆ์—์„œ ๋…ผ๋ฆฌ์ ์œผ๋กœ ๊ฐ์ฒด๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  package๋Š” ๋…ผ๋ฆฌ์  ๋ถ„๋ฆฌ๋งŒ์„ ์ˆ˜ํ–‰ํ•  ๋ฟ, ๋นŒ๋“œ์˜ ๋ฒ”์œ„์™€๋Š” ๊ด€๋ จ์ด ์—†๋‹ค. ๋”ฐ๋ผ์„œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌํ™”๊ฐ€ ๊ฐ€๋Šฅํ•œ module๊ณผ ๋‹ฌ๋ฆฌ package๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌํ™”๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค (์ข€ ๋” ์ •ํ™•ํžˆ๋Š”, ์• ์ดˆ์— ๊ฐ€๋Šฅใ†๋ถˆ๊ฐ€๋Šฅ์„ ๋…ผํ•  ์ˆ˜ ์—†๋‹ค).

 

#2 Module์˜ ์ข…๋ฅ˜

#2-1 AAR ํŒŒ์ผ๊ณผ APK ํŒŒ์ผ

์•ˆ๋“œ๋กœ์ด๋“œ ํ”„๋กœ์ ํŠธ๋ฅผ ๋นŒ๋“œํ–ˆ๋‹ค๊ณ  ๋ฐ˜๋“œ์‹œ (์Šค๋งˆํŠธํฐ ์ƒ์—์„œ) ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๊ฑด ์•„๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋นŒ๋“œ์˜ ๊ฒฐ๊ณผ๋ฌผ์€ AAR(Android ARchive) ํŒŒ์ผ ๋˜๋Š” APK(Android PacKage) ํŒŒ์ผ์ธ๋ฐ, ์ด ์ค‘ APK ํŒŒ์ผ๋งŒ์ด ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ํŒŒ์ผ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.AAR ํŒŒ์ผ์€ ์ด๋ฆ„(Android ARchive)์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์‚ฌ์šฉ๋˜๊ธฐ ์œ„ํ•œ ํŒŒ์ผ์ด๋‹ค. AAR ํŒŒ์ผ์€ APK ํŒŒ์ผ์— ๋˜๋Š” ๋˜ ๋‹ค๋ฅธ AAR ํŒŒ์ผ์— ์ข…์†๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์‚ฌ์šฉ๋œ๋‹ค. APK ํŒŒ์ผ์€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ AAR ํŒŒ์ผ์„ ์ทจํ•˜์ง€๋งŒ, ๊ธฐ๋ณธ์ ์œผ๋ก  ๋…๋ฆฝ ์‹คํ–‰์ด ๊ฐ€๋Šฅํ•œ ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ์ด๋‹ค.

 

#2-2 App Module

๋นŒ๋“œํ–ˆ์„๋•Œ APK ํŒŒ์ผ์ด ๋‚˜์˜ค๋Š” ๋ชจ๋“ˆ์ด๋‹ค. ์•ˆ๋“œ๋กœ์ด๋“œ ์ŠคํŠœ๋””์˜ค์—์„œ ๋นˆ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ–ˆ์„ ๋•Œ "app"์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๊ธฐ๋ณธ ์ƒ์„ฑ๋˜๋Š” ๋ชจ๋“ˆ์ด ๋ฐ”๋กœ App Module์ด๋‹ค. build.gradle์„ ๋ณด๋ฉด applicationId, target sdk, version code, version name, ... ๋“ฑ ๋…๋ฆฝ ์‹คํ–‰์„ ์œ„ํ•ด ํ•„์š”ํ•œ ๋‹ค์–‘ํ•œ ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค

 

#2-3 Library Module

๋นŒ๋“œํ–ˆ์„๋•Œ AAR ํŒŒ์ผ์ด ๋‚˜์˜ค๋Š” ๋ชจ๋“ˆ์ด๋‹ค. build.gradle์„ ๋ณด๋ฉด App Module๊ณผ๋Š” ๋‹ฌ๋ฆฌ ๋ˆ„๋ฝ๋œ ์ •๋ณด๊ฐ€ ๋งŽ๋‹ค. ๊ฐ€๋ น, applicationId๊ฐ€ ์—†๋‹ค. applicationId๋Š” Google Play Store์—์„œ ์•ฑ์„ ๊ตฌ๋ถ„ํ•˜๋Š” ์šฉ๋„, ์‹œ์Šคํ…œ์—์„œ ์•ฑ์„ ์‹๋ณ„ํ•˜๋Š” ์šฉ๋„๋กœ ์“ฐ์ด๋Š”๋ฐ Library Module์€ ์• ์ดˆ์•  ๋…๋ฆฝ ์‹คํ–‰์ด ์•ˆ๋˜๋ฏ€๋กœ ๊ตณ์ด applicationId๊ณผ ๊ฐ™์€ ์‹๋ณ„์ž๊ฐ€ ํ•„์š”์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

#2-4 ๋นŒ๋“œ ์ˆœ์„œ

App module๊ณผ Library module์ด ์„ž์ธ ํ”„๋กœ์ ํŠธ์—์„œ์˜ ๋นŒ๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ์ˆœ์„œ๋ฅผ ๋”ฐ๋ฅธ๋‹ค.

1. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชจ๋“ˆ 1: ์†Œ์Šค ์ฝ”๋“œ + ๋ฆฌ์†Œ์Šค (+ ํ•„์š”ํ•œ AAR) → AAR ํŒŒ์ผ
2. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชจ๋“ˆ 2: ์†Œ์Šค ์ฝ”๋“œ + ๋ฆฌ์†Œ์Šค (+ ํ•„์š”ํ•œ AAR) → AAR ํŒŒ์ผ
3. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชจ๋“ˆ 3: ์†Œ์Šค ์ฝ”๋“œ + ๋ฆฌ์†Œ์Šค (+ ํ•„์š”ํ•œ AAR) → AAR ํŒŒ์ผ
...
n. ์•ฑ ๋ชจ๋“ˆ: ์†Œ์Šค ์ฝ”๋“œ + ๋ฆฌ์†Œ์Šค + (+ ํ•„์š”ํ•œ AAR) → APK ํŒŒ์ผ

 

#3 ๋ชจ๋“ˆ ๊ตฌํ˜„ํ•ด๋ณด๊ธฐ

์™„์„ฑ๋œ ํ”„๋กœ์ ํŠธ๋Š” #4์—์„œ ์ „์ฒด ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

#3-1 ๋ ˆํผ๋Ÿฐ์Šค ์ฝ”๋“œ

 

[Android] Retrofit - MVVM ๊ตฌ์กฐ

#1 ์ด์ „ ๊ธ€ [Android] Retrofit - ๊ธฐ์ดˆ#1 ์ด์ „ ๊ธ€ [Android] Retrofit - ๋ฐฐ๊ฒฝ๊ณผ ๊ตฌ์กฐ#1 Restrofit์˜ ๋ฐฐ๊ฒฝ#1-1 REST API REST API (REpresentational State Transfer Application Programming Interface)#1 ๋ฌด์—‡(What)์— ๋Œ€ํ•œ API์ธ๊ฐ€?#1-1 ๊ฐœ์š”RE

kenel.tistory.com

์˜ˆ์ „์— ๋งŒ๋“ค์–ด๋‘” ์ฝ”๋“œ๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•ด์„œ 2๊ฐœ์˜ ๋ชจ๋“ˆ๋กœ ๋‚˜๋ˆ„๊ฒ ๋‹ค. ๋จผ์ € ์œ„ ๊ฒŒ์‹œ๊ธ€์— ์žˆ๋Š” '์™„์„ฑ๋œ ์•ฑ'์„ ๊ทธ๋Œ€๋กœ ๊ฐ€์ ธ์™”๋‹ค. ๊ธฐ๋ณธ ๋ชจ๋“ˆ์ธ "app"์— ๋“ค์–ด์žˆ๋Š” retrofit ๊ด€๋ จํ•œ ์ฝ”๋“œ๋“ค์„, "network"๋ผ๋Š” ์ƒˆ ๋ชจ๋“ˆ๋กœ ์˜ฎ๊ธธ ์ž‘์ •์ด๋‹ค (๋ฉ€ํ‹ฐ ๋ชจ๋“ˆํ™”).

 

#3-2 ๋ชจ๋“ˆ ๋งŒ๋“ค๊ธฐ

[Project ํƒญ์—์„œ ๋นˆ ๊ณต๊ฐ„ ์šฐํด๋ฆญ] -> [New] -> [Module]
๋˜๋Š” [File] -> [New] -> [New Module...]

 

[Create New Module] -> [Android Library] -> [๋ชจ๋“ˆ ์ด๋ฆ„ ์„ค์ • (์—ฌ๊ธฐ์„œ๋Š” "network")] -> [๋‚˜๋จธ์ง€๋Š” ๊ทธ๋Œ€๋กœ ๋‘๊ณ  Finish]


์–ด์จŒ๋“  ์ด๋ ‡๊ฒŒ ์ƒˆ ๋ชจ๋“ˆ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฑด ๊ธฐ๋ณธ ๋ชจ๋“ˆ์ธ "app" ๋ชจ๋“ˆ์„ ๋ณต์ œํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๊ณผ์ •์ด๋‹ค. ๊ฐ“ ๋งŒ๋“ค์–ด์ง„ network ๋ชจ๋“ˆ์„ ๋ณด๋ฉด res ํด๋”๊ฐ€ ์—†๋‹ค. ๋ฌผ๋ก  ๋„คํŠธ์›Œํฌ ๊ด€๋ จ ์ฝ”๋“œ๋ฅผ ๋„ฃ์„ ๊ฒƒ์ด๋ฏ€๋กœ res ํด๋”๊ฐ€ ์žˆ์„ ์ด์œ ๋„ ์—†๊ฒ ์ง€๋งŒ, ํ•„์š”ํ•˜๋‹ค๋ฉด app ๋ชจ๋“ˆ์ด res ํด๋”๋ฅผ ์ง€๋‹ˆ๊ณ  ์žˆ๋Š” ๊ฒƒ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ทธ๋ƒฅ ์ƒ์„ฑํ•ด์ฃผ๋ฉด ๊ทธ๋งŒ์ผ ๊ฒƒ์ด๋‹ค.

 

#3-3 ์ฝ”๋“œ ๋‚˜๋ˆ„๊ธฐ

"app" ๋ชจ๋“ˆ์— ์žˆ๋˜ "retrofit" ํŒจํ‚ค์ง€์˜ ๋ชจ๋“  ํŒŒ์ผ์„ "network" ๋ชจ๋“ˆ๋กœ ์˜ฎ๊ฒผ๋‹ค. ์ด์–ด์„œ, "retrofit" ํŒจํ‚ค์ง€๋Š” ์‚ญ์ œํ•œ๋‹ค. 

 

implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")

์˜ฎ๊ธด ์ฝ”๋“œ๋“ค์€ retrofit ๋ฐ gson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์ข…์†๋˜์–ด ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ "network" ๋ชจ๋“ˆ ์† build.gradle ํŒŒ์ผ์˜ dependencies { ... }์— ์œ„์™€ ๊ฐ™์ด retrofit ๋ฐ gson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

 

#3-4 ๊ฐ€์‹œ์„ฑ ํ™•๋ณด

#3-3์—์„œ ์ฝ”๋“œ๋ฅผ ์˜ฎ๊ฒผ๋‹ค๊ณ  ๋๋‚œ ๊ฑธ๊นŒ? ์•„๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด, "app" ๋ชจ๋“ˆ์€ "network" ๋ชจ๋“ˆ์˜ ์กด์žฌ๋ฅผ ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์• ์ดˆ์— ์„œ๋กœ ๋…๋ฆฝ์ ์œผ๋กœ ๋นŒ๋“œ๋˜๋Š”, ๋ชจ๋“ˆ์˜ ๋‹จ์œ„๊ฐ€ ๋‹ค๋ฅด๊ธฐ์— ์„œ๋กœ ์•Œ ์ด์œ ๋„ ์—†๋‹ค (import๋ฌธ ํ•œ ์ค„๋กœ ๋ฐ”๋กœ ์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์—ˆ๋˜ package ๋‹จ์œ„์™€ ๋Œ€๋น„๋œ๋‹ค).

 

"app" ๋ชจ๋“ˆ์ด "network" ๋ชจ๋“ˆ์˜ ์ฝ”๋“œ๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ ค๋ฉด (= ๊ฐ€์‹œ์„ฑ์„ ํ™•๋ณดํ•˜๋ ค๋ฉด), "app" ๋ชจ๋“ˆ ์† build.gradle์˜ dependencies { ... }์— "network" ๋ชจ๋“ˆ์˜ ์ •๋ณด๋ฅผ ์ ์–ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

implementation(project(":network"))

์œ„์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ ์œผ๋ฉด, "app" ๋ชจ๋“ˆ์ด "network" ๋ชจ๋“ˆ์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

 

์ฃผ์˜ํ•  ์ ์€, ๋‹น์—ฐํ•˜๊ฒŒ๋„ private ์ ‘๊ทผ์ œ์–ด์ž๊ฐ€ ๋ถ™์€ ์ฝ”๋“œ๋Š” ๋ฌด์Šจ ์ง“์„ ํ•ด๋„ ์ฐธ์กฐํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ํŒŒ์ผ ๋‹จ์œ„์˜ ์ฐธ์กฐ ๋ฒ”์œ„๋ฅผ ์ง€๋‹ˆ๋Š” private ๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“ˆ ๋‹จ์œ„์˜ ์ฐธ์กฐ ๋ฒ”์œ„๋ฅผ ์ง€๋‹ˆ๋Š” internal ๋ชจ๋‘ ์ฐธ์กฐํ•  ์ˆ˜ ์—†๋‹ค. Library Module์„ ๋งŒ๋“ค ๋•Œ๋Š”, ๋˜ ๋‹ค๋ฅธ Library Module ๋˜๋Š” App Module์— ๊ณต๊ฐœ์ ์œผ๋กœ ์ œ๊ณตํ•  API๋งŒ์„ public ์ ‘๊ทผ์ œ์–ด์ž๋กœ ๋‘ฌ์•ผํ•  ๊ฒƒ์ด๋‹ค.

#4 ์™„์„ฑ๋œ ์•ฑ

 

android-practice/architecture/ModuleSample at master · Kanmanemone/android-practice

Contribute to Kanmanemone/android-practice development by creating an account on GitHub.

github.com

 

#5 ์ฐธ๊ณ 

'๊นจ์•Œ ๊ฐœ๋… ๐Ÿ“‘ > Android' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Android] Pointer input - Drag  (0) 2025.05.13
[Android] App layout - Custom layouts  (0) 2025.02.27
[Android] UI architecture - Phase์™€ State  (1) 2025.02.27
[Android] UI architecture - Phases  (0) 2025.02.27
[Android] App layout - ๊ธฐ์ดˆ  (0) 2025.02.27