Android 代碼架構通常包括四個主要層次:應用層、框架層、原生層和 Linux 內核層。下面我們用 mermaid 圖來表示:
結合這個圖示來詳細闡述 Android 代碼架構:
應用層(Application Layer):
框架層(Framework Layer):
原生層(Native Layer):
Linux 內核層(Linux Kernel Layer):
除了上述層次,Android 架構中還包含了一些重要的元件和概念,如:
Android 應用架構的核心思想是分離關注點 和 數據驅動 UI。架構的演進是為了讓代碼更易於測試、維護和團隊協作。
下面我們以 MVVM 為核心,結合 Jetpack 元件,來剖析一個完整的、現代的 Android 應用架構。
三個核心層以及它們之間的依賴關係:UI 層 -> 領域層 -> 數據層。數據流是單向的。
職責:在螢幕上顯示應用數據,並處理用戶互動。
核心技術:
StateFlow
是 Kotlin 協程中的現代選擇,與 Compose 配合極佳。代碼示例 (Compose + ViewModel + StateFlow):
// 1. ViewModel
class MainViewModel(
private val getPostsUseCase: GetPostsUseCase // 使用用例
) : ViewModel() {
// UI 狀態使用 StateFlow 暴露
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
init {
loadPosts()
}
private fun loadPosts() {
viewModelScope.launch {
_uiState.value = UiState.Loading
try {
val posts = getPostsUseCase()
_uiState.value = UiState.Success(posts)
} catch (e: Exception) {
_uiState.value = UiState.Error(e.message ?: "未知錯誤")
}
}
}
}
// 密封類(Sealed Class)用來表示所有可能的 UI 狀態
sealed class UiState {
object Loading : UiState()
data class Success(val posts: List<Post>) : UiState()
data class Error(val message: String) : UiState()
}
// 2. Composable UI
@Composable
fun MainScreen(
viewModel: MainViewModel = hiltViewModel() // 使用 Hilt 依賴注入獲取 ViewModel
) {
val uiState by viewModel.uiState.collectAsState()
when (val state = uiState) {
is UiState.Loading -> {
CircularProgressIndicator()
}
is UiState.Success -> {
LazyColumn {
items(state.posts) { post ->
PostItem(post = post)
}
}
}
is UiState.Error -> {
Text(text = "錯誤: ${state.message}", color = Color.Red)
}
}
}
@Composable
fun PostItem(post: Post) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
) {
Column(modifier = Modifier.padding(16.dp)) {
Text(text = post.title, fontWeight = FontWeight.Bold)
Spacer(modifier = Modifier.height(4.dp))
Text(text = post.body)
}
}
}
職責:封裝複雜的商業邏輯,或組合多個 Repository 的調用。它是一個可選層,但對於複雜商業邏輯非常有用,可以使代碼更清晰、可重用。
核心技術:
代碼示例:
// 獲取帖子列表的用例
class GetPostsUseCase(
private val postsRepository: PostsRepository
) {
// 使用‘operator invoke’可以讓調用像函數一樣簡單:useCase()
suspend operator fun invoke(): List<Post> {
// 在這裡可以添加商業邏輯,比如過濾、排序等
return postsRepository.getPosts()
}
}
// 另一個例子:刷新帖子數據的用例
class RefreshPostsUseCase(
private val postsRepository: PostsRepository
) {
suspend operator fun invoke() {
postsRepository.refreshPosts()
}
}
職責:管理應用的數據,包括來自網路、本地數據庫等多種數據源。它提供單一的數據入口給上層。
核心技術:
代碼示例:
// 1. Data Class (Entity)
@Entity(tableName = "posts")
data class Post(
@PrimaryKey val id: Int,
val title: String,
val body: String
)
// 2. Retrofit API Interface
interface PostsApiService {
@GET("posts")
suspend fun getPosts(): List<Post>
}
// 3. Room Dao (Data Access Object)
@Dao
interface PostDao {
@Query("SELECT * FROM posts")
fun getPosts(): Flow<List<Post>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(posts: List<Post>)
}
// 4. Repository 實現
class DefaultPostsRepository(
private val apiService: PostsApiService,
private val postDao: PostDao,
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
) : PostsRepository {
// 對外暴露一個 Flow,這樣 UI 可以持續觀察數據庫的變化
override fun getPosts(): Flow<List<Post>> {
return postDao.getPosts()
}
// 刷新策略:網路優先,失敗則使用快取
override suspend fun refreshPosts() {
withContext(ioDispatcher) {
try {
val posts = apiService.getPosts()
postDao.insertAll(posts)
} catch (e: Exception) {
// 處理網路錯誤,例如拋出錯誤狀態或使用快取
throw e
}
}
}
}
為什麼重要:它管理著類之間的依賴關係,使得代碼更鬆散耦合、更易測試。
核心技術:
代碼示例:
// 1. 使用 Hilt 定義依賴
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun providePostsApiService(): PostsApiService {
return Retrofit.Builder()
.baseUrl("https://jsonplaceholder.typicode.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(PostsApiService::class.java)
}
@Provides
@Singleton
fun providePostDatabase(@ApplicationContext context: Context): PostDatabase {
return Room.databaseBuilder(
context,
PostDatabase::class.java,
"posts.db"
).build()
}
}
@Module
@InstallIn(ViewModelComponent::class)
object UseCaseModule {
@Provides
fun provideGetPostsUseCase(repository: PostsRepository): GetPostsUseCase {
return GetPostsUseCase(repository)
}
}
// 2. 在 ViewModel 中使用 Hilt 注入
@HiltViewModel
class MainViewModel @Inject constructor(
private val getPostsUseCase: GetPostsUseCase // Hilt 自動注入
) : ViewModel() { ... }
遵循一個由淺入深、理論與實踐結合的路徑:
launch
、async
、flow
等基本概念。現代 Android 架構是一個圍繞 MVVM、分層設計、單向數據流 和 響應式編程 構建的生態系統。核心技術棧是 Kotlin + Jetpack (ViewModel, Room, Compose) + Coroutines/Flow + Hilt。
從簡單開始,然後逐步將學到的每一項新技術應用到專案中,不斷重構和優化你的代碼結構。通過實踐,才能真正理解和掌握這套強大的架構。