notes
Andriod - kotlin
Android Kotlin 문법·구조와 앱 개발에서 사용하는 기본 개념 메모.
Kotlin 공식/안드로이드 코드랩 북마크를 여기 붙여 두었었다. 지금 본문에 .kt 확장자·null 안전·디렉토리(data/domain/presentation)·MVVM 뼈대가 그 내용이다.
1.확장자명은 .kt
2.
현재 Android 공식 개발 언어가 Kotlin이며, Java보다 권장
Java(.java)로도 개발 가능하지만, 구글이 Kotlin을 선호
Kotlin의 장점:
Null 안정성
간결한 문법
Java와 100% 호환
함수형 프로그래밍 지원
디렉토리
app/
├── manifests/
│ └── AndroidManifest.xml
├── java/
│ └── com.example.app/
│ ├── data/ # 데이터 계층
│ │ ├── api/ # 네트워크 통신
│ │ ├── repository/ # 저장소
│ │ └── model/ # 데이터 모델
│ ├── di/ # 의존성 주입
│ ├── domain/ # 비즈니스 로직
│ │ └── usecase/ # 유스케이스
│ ├── presentation/ # UI 계층
│ │ ├── main/ # 화면별 패키지
│ │ ├── detail/
│ │ └── common/ # 공통 컴포넌트
│ └── util/ # 유틸리티
└── res/
- 주요 아키텍처 패턴
- 주요 아키텍처 패턴
a) Clean Architecture (가장 많이 사용)
참고:
Clean Architecture 다이어그램 북마크 자리. 한 줄로: UI(presentation) → domain usecase → data(repository/api/db). 의존성은 안쪽(domain)을 바라보게.
MVVM
(권장되는 UI 패턴)
- ViewModel: UI 로직 처리
- View: UI 표시
- Model: 데이터 처리
주요 구성요소
// UI 컴포넌트
class MainActivity : AppCompatActivity()
class MainFragment : Fragment()
// ViewModel
class MainViewModel : ViewModel()
// Repository
class UserRepository @Inject constructor(
private val api: ApiService,
private val db: AppDatabase
)
// UseCase
class GetUserUseCase @Inject constructor(
private val repository: UserRepository
)
- 자주 사용되는 라이브러리
- Dagger Hilt: 의존성 주입
- Retrofit: 네트워크 통신
- Room: 로컬 데이터베이스
- Coroutines: 비동기 처리
- Jetpack Compose: 현대적 UI 개발
변수 선언
// 변수 (가변)
var name: String = "Kim"
var age = 25 // 타입 추론
// 상수 (불변)
val PI = 3.14
데이터 타입
함수선언
// 기본 함수
fun sum(a: Int, b: Int): Int {
return a + b
}
// 한 줄 함수
fun sum(a: Int, b: Int) = a + b
// 기본값 있는 함수
fun greet(name: String = "Guest") = "Hello $name"
nullable 처리
// Nullable 타입
var name: String? = null
// Null 안전 호출
val length = name?.length // name이 null이면 length도 null
// Elvis 연산자
val length = name?.length ?: 0 // null이면 0 반환
// Not-null 단언
val length = name!!.length // null이면 예외 발생
조건문
// if-else (식으로 사용 가능)
val max = if (a > b) a else b
// when (switch 대체)
when (x) {
1 -> print("One")
2, 3 -> print("Two or Three")
in 4..10 -> print("Between 4 and 10")
else -> print("Other")
}
반복문
// for
for (i in 1..10) { } // 1부터 10까지
for (i in 1 until 10) { } // 1부터 9까지
for (i in 10 downTo 1) { } // 10부터 1까지
for (i in 1..10 step 2) { } // 2씩 증가
// while
while (condition) { }
컬렉션 (arrary ,tuple 과 같은 개념 )
// List
val list = listOf(1, 2, 3) // 불변
val mutableList = mutableListOf(1, 2, 3) // 가변
// Map
val map = mapOf("a" to 1, "b" to 2)
val mutableMap = mutableMapOf<String, Int>()
// Set
val set = setOf(1, 2, 3)
클래스
// 기본 클래스
class Person(val name: String, var age: Int)
// 데이터 클래스
data class User(val name: String, val age: Int)
// 상속
open class Animal(val name: String)
class Dog(name: String): Animal(name)
// object (싱글톤)
object DatabaseConfig {
val url = "jdbc:mysql://localhost"
}
람다
// 람다 기본
val sum = { x: Int, y: Int -> x + y }
// 고차 함수
fun operation(x: Int, y: Int, op: (Int, Int) -> Int): Int {
return op(x, y)
}
확장 함수
fun String.addHello(): String {
return "Hello $this"
}
// 사용: "World".addHello() // "Hello World"
스코프 함수
// let
user?.let { it.name = "New Name" }
// with
with(user) {
name = "New Name"
age = 25
}
// apply
user.apply {
name = "New Name"
age = 25
}
// also
user.also {
println(it.name)
}
// run
user.run {
name = "New Name"
age = 25
}
코루틴 (Coroutines , thread)
- 비동기 프로그래밍kotlin
// 코루틴 스코프
launch {
delay(1000L)
println("World!")
}
// 비동기 함수
suspend fun fetchUser(): User
suspend fun fetchData() = coroutineScope {
val user = async { fetchUser() }
val data = async { fetchData() }
user.await() + data.await()
}
제네릭 (Generics)
// 제네릭 클래스
class Box<T>(var value: T)
// 제네릭 제약
class Box<T : Number>(var value: T)
// 변성
class Producer<out T> // 공변성
class Consumer<in T> // 반공변성
Sealed 클래스/인터페이스
sealed class Result {
data class Success(val data: String): Result()
data class Error(val message: String): Result()
object Loading: Result()
}
위임
// 프로퍼티 위임
class Example {
var name: String by Delegates.observable("") {
prop, old, new -> println("$old -> $new")
}
}
// 인터페이스 위임
class DelegatingCollection<T>(
private val collection: Collection<T>
) : Collection<T> by collection
타입 알리아스
typealias NetworkHandler = (Result<String>) -> Unit
typealias StringMap = Map<String, String>
중위 함수 (Infix functions)
infix fun Int.plus(x: Int) = this + x
// 사용: 1 plus 2
연산자 오버로딩
operator fun Point.plus(other: Point): Point {
return Point(x + other.x, y + other.y)
}
DSL 빌더
fun buildHTML() = html {
head {
title { +"Title" }
}
body {
div {
+"Content"
}
}
}
리플렉션
val kClass = String::class
val properties = kClass.memberProperties
어노테이션
@Target(AnnotationTarget.CLASS)
annotation class MyAnnotation
@MyAnnotation
class Example
인라인 함수
inline fun <T> lock(lock: Lock, body: () -> T): T {
lock.lock()
try {
return body()
} finally {
lock.unlock()
}
}
컨텍스트 리시버
fun List<Int>.sum() with Calculator {
var sum = 0
for (item in this) {
sum = add(sum, item)
}
return sum
}