🦾 Android | 하단 바 + Navigation Compose + 보안 키 주입(ResValue) 적용기
하단바 만들기 예제
개요 (Intro)
오늘의 목표 / 배경: 앱에 하단 바를 도입하고 Compose Navigation으로 홈/설정/광고 탭을 구성. 외부 API 키를 local.properties에서 안전하게 읽어 리소스로 주입.
어떤 문제를 해결하려 했는지: Gradle Kotlin DSL에서 local.properties 로딩 시 IDE 경고/오류, 네비게이션 구성 시 일부 import 누락 및 경고.
사용한 기술 스택: Kotlin, Jetpack Compose, Navigation-Compose, Hilt, Gradle Kotlin DSL
📅 날짜: 2025.11.23
🎯 목표: 바텀 네비게이션 3탭(홈/설정/광고) + 키 주입(resValue) + Gradle DSL 정리
🧰 기술: Kotlin, Compose, Navigation, Hilt, Gradle Kotlin DSL
문제 정의 (Problem / Motivation)
local.properties 값을 build.gradle.kts에서 java.util.Properties로 직접 로딩 시 IDE가 Unresolved reference: util, load 등 오탐 경고를 표시.
Compose 네비게이션 구현 중, Modifier.padding(innerPadding) 관련 import 누락으로 Unresolved reference 'padding' 오류.
하단 바와 NavHost를 연결하는 구조에서 패키지 경로, 아이콘 import, 경고(예: hiltViewModel deprecate 알림) 확인 필요.
// (이슈 예시) build.gradle.kts에서 직접 Properties 로딩 시 IDE 경고 발생 가능 val localProps = java.util.Properties().apply { val file = rootProject.file("local.properties") if (file.exists()) file.inputStream().use { load(it) } // load 참조 경고/오류 표기 사례 } val cupangAccessKey = localProps.getProperty("cupangAccessKey") ?: ""
해결 과정 (How I Solved It)
local.properties 로딩은 Gradle의 providers.gradleProperty API로 대체하여 IDE/Gradle 모두에서 안정적으로 동작하도록 변경.
앱 모듈의 defaultConfig에서 resValue로 문자열 리소스로 주입.
하단 바 + NavHost 구조를 분리 파일로 구성하고, 필요한 Compose import를 명시하여 컴파일 오류 제거.
// app/build.gradle.kts (발췌) — Gradle providers API 사용 val cupangAccessKey: String = providers.gradleProperty("cupangAccessKey").orNull ?: "" val cupangSecretKey: String = providers.gradleProperty("cupangSecretKey").orNull ?: "" android { defaultConfig { resValue("string", "cupang_access_key", cupangAccessKey) resValue("string", "cupang_secret_key", cupangSecretKey) } }
// 하단 바 + 네비게이션 (발췌) sealed class AppScreen(val route: String, val label: String, val icon: ImageVector) { data object Home: AppScreen("home", "홈", Icons.Filled.Home) data object Settings: AppScreen("settings", "설정", Icons.Filled.Settings) data object Ads: AppScreen("ads", "광고", Icons.Filled.Campaign) } @Composable fun AppNavHost(navController: NavHostController, viewModel: HealthConnectViewModel = hiltViewModel()) { NavHost(navController = navController, startDestination = AppScreen.Home.route) { composable(AppScreen.Home.route) { MainScreen(viewModel) } composable(AppScreen.Settings.route) { SettingsScreen() } composable(AppScreen.Ads.route) { AdsScreen() } } } @Composable fun AppScaffoldWithBottomBar() { val navController = rememberNavController() Scaffold(bottomBar = { BottomBar(navController) }) { innerPadding -> Box(modifier = Modifier.padding(innerPadding)) { AppNavHost(navController) } } }
결과 (Result)
하단 바 3탭(홈/설정/광고) + NavHost 라우팅이 정상 작동.
local.properties의 cupangAccessKey/cupangSecretKey를 R.string으로 노출, 화면/Compose에서 getString으로 참조 가능.
Gradle Kotlin DSL의 IDE 경고를 줄이고, 스크립트 단순화로 유지보수성 개선.
✅ 바텀 네비게이션 안정화 및 화면 전환 확인
🔐 키 주입(resValue) 동작 확인, 보안 노출 리스크는 추후 서버 프록시로 추가 보완 예정
🧹 Gradle DSL 경고 제거로 개발 경험 개선
느낀 점 / 회고 (Reflection)
Gradle 스크립트에서 표준 API를 직접 다루기보다는 Gradle 제공 API를 활용하는 편이 IDE/빌드 모두에 일관적.
네비게이션은 파일 분리(화면/바/호스트)로 가독성이 크게 좋아짐.
민감 키는 최종적으로 서버 서명/프록시로 이동하는 게 안전. 일단은 resValue로 편의 제공.
참고자료 (References)
댓글 없음:
댓글 쓰기