Android代码架构通常包括四个主要层次:应用层、框架层、原生层和Linux内核层。下面我们用mermaid图来表示:
结合这个图示来详细阐述Android代码架构:
-
应用层(Application Layer) :
- 这是用户直接接触的层面,包括系统自带的应用程序(如联系人、短信、相机等)和第三方应用程序(如微信、淘宝等)。
- 应用层使用Java或Kotlin语言编写,运行在Android运行时(ART)上。
-
框架层(Framework Layer) :
-
框架层为应用层提供了大量的API,使开发者能够快速开发应用程序。框架层包含了各种管理器和服务,例如:
- Activity Manager:管理应用程序的生命周期和活动栈。
- Window Manager:管理窗口程序。
- Content Providers:管理应用程序间数据共享。
- View System:构建用户界面的基本组件。
- Notification Manager:管理通知。
- Package Manager:管理应用程序包。
- Telephony Manager:管理移动设备功能。
- Resource Manager:管理非代码资源(如图片、字符串等)。
- Location Manager:管理位置服务。
- XMPP Service:管理即时通讯服务。
-
框架层主要使用Java语言编写。
-
-
原生层(Native Layer) :
- 原生层包括原生C/C++库和Android运行时。
- 原生C/C++库:包括一系列C/C++库,如OpenGL ES、Webkit、SQLite等,这些库为Android系统提供了底层的功能支持。
- Android运行时:包括Dalvik虚拟机和ART。从Android 5.0开始,ART取代了Dalvik虚拟机。ART在应用安装时将字节码转换为机器码,提高了应用的运行效率。
- 原生层还包含了硬件抽象层(HAL),它提供了标准接口,使得框架层能够与硬件设备进行通信,而无需关心底层驱动实现。
-
Linux内核层(Linux Kernel Layer) :
- Android基于Linux内核,但增加了一些特定的驱动和功能,如电源管理、进程管理等。
- 该层包含了各种硬件驱动,如显示驱动、摄像头驱动、蓝牙驱动、USB驱动、键区驱动、WiFi驱动、音频驱动等。
- Linux内核层还负责系统安全、内存管理、进程管理、网络协议栈等。
除了上述层次,Android架构中还包含了一些重要的组件和概念,如:
- 四大组件:Activity、Service、BroadcastReceiver、ContentProvider。
- Intent:用于在组件之间传递消息。
- Binder:Android中的一种跨进程通信(IPC)机制。
- Handler:用于线程间通信,特别是在主线程(UI线程)和子线程之间。
- View和ViewGroup:构建用户界面的基础。
- 资源管理:如何管理图片、字符串、布局等资源。
- 清单文件(AndroidManifest.xml) :声明组件、权限等。
一、Android代码架构演进与核心思想
Android应用架构的核心思想是分离关注点 和数据驱动UI。架构的演进是为了让代码更易于测试、维护和团队协作。
- MVC:早期模式,但在Android中,Activity/Fragment经常承担了Controller和View的双重角色,导致它们过于臃肿。
- MVP:引入了Presenter层,将UI逻辑从Activity/Fragment中抽离出来,大大改善了可测试性。
- MVVM :当前主流和官方推荐 的架构。它利用数据绑定 和生命周期感知组件,实现了数据与UI的自动同步,进一步减少了模板代码。
二、现代Android应用架构详解
下面我们以MVVM为核心,结合Jetpack组件,来剖析一个完整的、现代的Android应用架构。
三个核心层以及它们之间的依赖关系:UI层 -> 领域层 -> 数据层。数据流是单向的。
三、各层核心技术详解与代码示例
1. UI层
职责:在屏幕上显示应用数据,并处理用户交互。
核心技术:
- Activity / Fragment:UI的容器,负责处理系统交互和生命周期。
- Jetpack Compose :现代首选的声明式UI工具包,用Kotlin代码构建界面。
- View System:传统的基于XML的UI系统。
- ViewModel :架构核心,为UI准备和管理数据。它能在配置变更(如屏幕旋转)后存活。
- LiveData / StateFlow :可观察的数据持有者。
StateFlow
是Kotlin协程中的现代选择,与Compose配合极佳。 - DataBinding / ViewBinding:用于将UI组件与数据源绑定。
代码示例 (Compose + ViewModel + StateFlow) :
kotlin
// 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 ?: "Unknown error")
}
}
}
}
// 密封类(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 = "Error: ${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)
}
}
}
2. 领域层
职责 :封装复杂的业务逻辑,或组合多个Repository的调用。它是一个可选层,但对于复杂业务逻辑非常有用,可以使代码更清晰、可复用。
核心技术:
- Use Cases / Interactors:每个UseCase应该只负责一个单一的业务功能。
代码示例:
kotlin
// 获取帖子列表的用例
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()
}
}
3. 数据层
职责:管理应用的数据,包括来自网络、本地数据库等多种数据源。它提供单一的数据入口给上层。
核心技术:
- Repository:架构核心,是数据的唯一来源。它决定从网络还是本地数据库获取数据,并处理缓存策略。
- Room:SQLite的对象映射库,用于本地数据持久化。
- Retrofit:类型安全的HTTP客户端,用于访问网络API。
- WorkManager:管理后台任务。
- Paging Library:分页加载数据。
代码示例:
kotlin
// 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
}
}
}
}
四、依赖注入 - 架构的粘合剂
为什么重要:它管理着类之间的依赖关系,使得代码更松散耦合、更易测试。
核心技术:
- Hilt :官方推荐的基于Dagger的DI库,极大简化了Android上的DI配置。
代码示例:
kotlin
// 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() { ... }
五、如何掌握
遵循一个由浅入深、理论与实践结合的路径:
第一阶段:基础入门
- Kotlin语言:掌握基础语法、数据类、密封类、扩展函数、Lambda表达式。
- Android基础:Activity/Fragment生命周期、常用布局和控件。
- 构建第一个App:一个简单的静态界面App。
第二阶段:核心架构与异步编程
- ViewModel & LiveData/StateFlow:理解为何要使用它们,并在项目中实践。
- Coroutines :重中之重 !理解协程的作用,掌握
launch
,async
,flow
等基本概念。 - Room:学习本地数据库操作。
- Retrofit:学习网络请求。
- 项目实践:构建一个简单的"待办事项"或"新闻阅读"App,使用以上所有技术,实现数据的增删改查。
第三阶段:进阶与现代化工具
- Jetpack Compose:开始学习声明式UI。从基础组件和状态管理入手。
- Hilt:在之前的项目中引入Hilt,管理所有依赖。
- Repository模式:重构你的"新闻阅读"App,明确分离数据层和UI层。
第四阶段:精通与最佳实践
-
Use Cases:在更复杂的项目中引入领域层。
-
Paging 3.0:学习列表分页。
-
Navigation:学习应用内页面导航。
-
Testing:为ViewModel、Repository、UseCase编写单元测试,为UI编写仪器测试。
-
关注官方资源:
- Android Developers官网:有最权威的指南和文档。
- Now in Android:Google官方示例项目,展示了所有最新最佳实践。
- Google Codelabs:提供手把手的免费教程。
总结
现代Android架构是一个围绕 MVVM 、分层设计 、单向数据流 和 响应式编程 构建的生态系统。核心技术栈是 Kotlin + Jetpack (ViewModel, Room, Compose) + Coroutines/Flow + Hilt。
从简单开始,然后逐步将学到的每一项新技术应用到项目中,不断重构和优化你的代码结构。通过实践,才能真正理解和掌握这套强大的架构。