Android — Kotlin
Standar pengembangan aplikasi Android menggunakan Kotlin sebagai bahasa utama.
Tech Stack
| Kategori | Library / Tool | Versi Min. |
|---|---|---|
| Language | Kotlin | 2.4+ (K2 compiler) |
| Min SDK | API 24 (Android 7.0) | — |
| Target SDK | API 36 (Android 16) | Wajib untuk app baru per 31 Agu 2026 |
| Build System | Gradle (Kotlin DSL) | 9.x |
| UI | Jetpack Compose | Latest (via Compose BOM) |
| Navigation | Compose Navigation | Latest |
| DI | Hilt / Koin | Latest |
| Networking | Retrofit + OkHttp | 3.x + 5.x |
| Serialization | Kotlinx Serialization | Latest |
| Image Loading | Coil | 3.x (io.coil-kt.coil3, Kotlin Multiplatform) |
| Local DB | Room | Latest |
| State Management | ViewModel + StateFlow | — |
| Testing | JUnit 5, MockK, Turbine | — |
| CI/CD | Fastlane + GitLab CI | — |
Project Structure
app/
├── src/
│ ├── main/
│ │ ├── java/com/bitgroup/appname/
│ │ │ ├── data/ # Data layer
│ │ │ │ ├── remote/ # API services & DTOs
│ │ │ │ ├── local/ # Room DAOs & entities
│ │ │ │ └── repository/ # Repository implementations
│ │ │ ├── domain/ # Domain layer
│ │ │ │ ├── model/ # Domain models
│ │ │ │ ├── repository/ # Repository interfaces
│ │ │ │ └── usecase/ # Use cases
│ │ │ ├── presentation/ # Presentation layer
│ │ │ │ ├── ui/ # Composable screens
│ │ │ │ ├── viewmodel/ # ViewModels
│ │ │ │ └── navigation/ # Nav graph
│ │ │ ├── di/ # Hilt modules
│ │ │ └── core/ # Utilities, extensions
│ │ └── res/
│ └── test/ # Unit tests
│ └── androidTest/ # Instrumented tests
├── build.gradle.kts
└── gradle/
└── libs.versions.toml # Version catalog
Coding Standards
Kotlin Style Guide
- Ikuti Kotlin Coding Conventions resmi.
- Gunakan
ktlintataudetektsebagai linter. - Maksimum line length: 120 karakter.
Jetpack Compose Best Practices
// ✅ Good - Stateless composable
@Composable
fun UserCard(
user: UserUiModel,
onTap: () -> Unit,
modifier: Modifier = Modifier,
) {
Card(
modifier = modifier.clickable(onClick = onTap),
) {
Text(text = user.name)
}
}
// ❌ Bad - Business logic inside composable
@Composable
fun UserCard(userId: String) {
val user = repository.getUser(userId) // Jangan!
Text(text = user.name)
}
ViewModel Pattern
@HiltViewModel
class UserViewModel @Inject constructor(
private val getUserUseCase: GetUserUseCase,
) : ViewModel() {
private val _uiState = MutableStateFlow<UserUiState>(UserUiState.Loading)
val uiState: StateFlow<UserUiState> = _uiState.asStateFlow()
fun loadUser(id: String) {
viewModelScope.launch {
_uiState.value = UserUiState.Loading
getUserUseCase(id)
.onSuccess { _uiState.value = UserUiState.Success(it) }
.onFailure { _uiState.value = UserUiState.Error(it.message) }
}
}
}
sealed interface UserUiState {
data object Loading : UserUiState
data class Success(val user: User) : UserUiState
data class Error(val message: String?) : UserUiState
}
Build & Run
# Debug build
./gradlew assembleDebug
# Run unit tests
./gradlew test
# Run lint
./gradlew ktlintCheck
# Generate signed APK
./gradlew assembleRelease
Version Catalog
Semua dependency version harus didefinisikan di gradle/libs.versions.toml untuk konsistensi multi-module project.