App 프로젝트 구조 분석 및 개발 가이드
프로젝트 개요
현재 프로젝트는 Wear OS 전용 앱으로 설정되어 있습니다.
- 패키지명:
com.example.kotlinapp
- Wear OS Compose 기반
- Standalone 앱 (스마트폰 없이 독립 실행 가능)
현재 파일 구조
kotlin_app/
├── app/
│ ├── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/com/example/kotlinapp/
│ │ │ └── presentation/
│ │ │ ├── MainActivity.kt
│ │ │ └── theme/
│ │ │ └── Theme.kt
│ │ └── res/
│ │ ├── drawable/
│ │ ├── mipmap-*/
│ │ ├── values/
│ │ └── values-round/
│ ├── build.gradle.kts
│ └── proguard-rules.pro
├── gradle/
│ └── libs.versions.toml
├── build.gradle.kts
└── settings.gradle.kts
기술 스택
현재 사용 중인 라이브러리
- Compose BOM: 2024.09.00
- Wear Compose Material: 1.2.1
- Wear Compose Foundation: 1.2.1
- Play Services Wearable: 18.0.0
- Activity Compose: 1.8.0
- Core Splashscreen: 1.0.1
SDK 버전
- minSdk: 30 (Android 11 - Wear OS 3.0)
- targetSdk: 36
- compileSdk: 36
Mobile + Wear 앱 구조 제안
1. 멀티 모듈 아키텍처 (권장)
프로젝트를 Mobile과 Wear로 분리하려면 다음 구조를 추천합니다:
kotlin_app/
├── mobile/ # 스마트폰 앱 모듈
│ ├── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/com/example/kotlinapp/mobile/
│ │ ├── MainActivity.kt
│ │ ├── ui/
│ │ ├── viewmodel/
│ │ └── data/
│ └── build.gradle.kts
│
├── wear/ # 웨어러블 앱 모듈 (현재 app 모듈)
│ ├── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ └── java/com/example/kotlinapp/wear/
│ │ ├── MainActivity.kt
│ │ ├── presentation/
│ │ └── complication/
│ └── build.gradle.kts
│
├── shared/ # 공통 코드 모듈
│ ├── src/
│ │ └── main/
│ │ └── java/com/example/kotlinapp/shared/
│ │ ├── data/
│ │ │ ├── model/ # 데이터 모델
│ │ │ └── repository/ # 저장소 인터페이스
│ │ └── domain/
│ │ └── usecase/ # 비즈니스 로직
│ └── build.gradle.kts
│
├── gradle/
├── build.gradle.kts
└── settings.gradle.kts
2. 모듈별 역할
Mobile 모듈 (mobile/
)
- 스마트폰 UI (일반 Compose 사용)
- 데이터 입력 및 설정
- Wear 앱과의 데이터 동기화
- 백그라운드 서비스
Wear 모듈 (wear/
)
- Wear OS UI (Wear Compose 사용)
- 워치 페이스/컴플리케이션
- 간단한 데이터 표시 및 조작
- 센서 데이터 수집 (심박수, 걸음 수 등)
Shared 모듈 (shared/
)
- 데이터 모델 (Kotlin Data Class)
- 네트워크 통신 로직
- 데이터베이스 스키마
- Wearable Data Layer API 통신 프로토콜
코드 작성 위치 가이드
현재 구조에서 코드 추가하기
1. UI 화면 추가
위치: app/src/main/java/com/example/kotlinapp/presentation/screens/
// 예시: HomeScreen.kt
package com.example.kotlinapp.presentation.screens
import androidx.compose.runtime.Composable
import androidx.wear.compose.material.*
@Composable
fun HomeScreen() {
// Wear OS UI 구현
}
2. ViewModel 추가
위치: app/src/main/java/com/example/kotlinapp/presentation/viewmodel/
// 예시: MainViewModel.kt
package com.example.kotlinapp.presentation.viewmodel
import androidx.lifecycle.ViewModel
class MainViewModel : ViewModel() {
// 상태 관리 로직
}
3. 데이터 모델
위치: app/src/main/java/com/example/kotlinapp/data/model/
// 예시: UserData.kt
package com.example.kotlinapp.data.model
data class UserData(
val id: String,
val name: String
)
4. Repository (데이터 소스)
위치: app/src/main/java/com/example/kotlinapp/data/repository/
// 예시: UserRepository.kt
package com.example.kotlinapp.data.repository
interface UserRepository {
suspend fun getUser(): UserData
}
5. Navigation
위치: app/src/main/java/com/example/kotlinapp/presentation/navigation/
// 예시: NavGraph.kt
package com.example.kotlinapp.presentation.navigation
import androidx.navigation.NavHostController
import androidx.wear.compose.navigation.SwipeDismissableNavHost
6. Utils/Extensions
위치: app/src/main/java/com/example/kotlinapp/utils/
Mobile + Wear 앱 구현 방법
방법 1: 별도 프로젝트로 분리
- Mobile 앱과 Wear 앱을 완전히 독립된 프로젝트로 개발
- 장점: 각각 독립적으로 배포 및 관리 가능
- 단점: 코드 중복 가능성, 동기화 어려움
방법 2: 멀티 모듈 프로젝트 (권장)
- 하나의 프로젝트 안에 mobile, wear, shared 모듈 구성
- 장점: 코드 공유 용이, 일관된 버전 관리
- 단점: 초기 설정 복잡도 증가
방법 3: Flavor 활용
- buildType flavor로 mobile/wear 구분
- 장점: 프로젝트 구조 간단
- 단점: UI 라이브러리가 달라서 관리 어려움
멀티 모듈 구성 방법
1. settings.gradle.kts 수정
rootProject.name = "Kotlin App"
include(":mobile")
include(":wear")
include(":shared")
2. 현재 app 모듈을 wear로 변경
# 디렉토리 이름 변경
mv app wear
3. mobile 모듈 생성
Android Studio에서:
- File > New > New Module
- “Phone & Tablet Module” 선택
- Module name: “mobile”
- Package name: com.example.kotlinapp.mobile
4. shared 모듈 생성
Android Studio에서:
- File > New > New Module
- “Android Library” 선택
- Module name: “shared”
- Package name: com.example.kotlinapp.shared
5. shared 모듈의 build.gradle.kts
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
}
android {
namespace = "com.example.kotlinapp.shared"
compileSdk = 36
defaultConfig {
minSdk = 30
}
}
dependencies {
// 공통 라이브러리
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
}
6. mobile/wear 모듈에서 shared 참조
dependencies {
implementation(project(":shared"))
// 기타 의존성...
}
Mobile-Wear 데이터 통신
Wearable Data Layer API 사용
shared 모듈에 공통 상수 정의
// shared/src/main/java/com/example/kotlinapp/shared/WearableConstants.kt
object WearableConstants {
const val DATA_PATH = "/kotlin_data"
const val MESSAGE_PATH = "/kotlin_message"
}
Mobile에서 데이터 전송
// mobile 모듈
import com.google.android.gms.wearable.*
class DataSender(private val context: Context) {
private val dataClient: DataClient by lazy {
Wearable.getDataClient(context)
}
suspend fun sendData(data: ByteArray) {
val putDataReq = PutDataMapRequest.create(WearableConstants.DATA_PATH).run {
dataMap.putByteArray("data", data)
asPutDataRequest()
}
dataClient.putDataItem(putDataReq).await()
}
}
Wear에서 데이터 수신
// wear 모듈
class DataReceiver(context: Context) : WearableListenerService() {
override fun onDataChanged(dataEvents: DataEventBuffer) {
dataEvents.forEach { event ->
if (event.dataItem.uri.path == WearableConstants.DATA_PATH) {
val data = DataMapItem.fromDataItem(event.dataItem)
.dataMap.getByteArray("data")
// 데이터 처리
}
}
}
}
권장 아키텍처 패턴
MVVM (Model-View-ViewModel)
presentation/
├── screens/ # Composable UI
│ ├── HomeScreen.kt
│ └── DetailScreen.kt
├── viewmodel/ # ViewModel
│ ├── HomeViewModel.kt
│ └── DetailViewModel.kt
└── navigation/ # Navigation Graph
data/
├── model/ # 데이터 모델
├── repository/ # Repository 구현
└── source/ # 데이터 소스 (local/remote)
domain/
├── usecase/ # 비즈니스 로직
└── repository/ # Repository 인터페이스
다음 단계
- 현재 단일 모듈(Wear only) 유지 vs 멀티 모듈 전환 결정
- Mobile 앱 필요 여부 확인
- 데이터 공유 방식 결정 (Wearable Data Layer, Firebase, REST API 등)
- UI/UX 설계
- 기능 구현 시작