博主2017年之前也开发android应用,如今业余兴趣玩鸿蒙了。现在再看如今的android开发,前后对比,像是完全变了个样。博主之前还吐槽android界面的xml页面写起来像是开老爷车,现在看起来android开发也变得简单了,是变得更好了。这样的UI写起来才更现代和符合主流。接下来介绍分享下从XML到Compose:现代Android开发指南,分享给有需要的小伙伴。
对于2017年之前涉足Android开发的开发者而言,如今的开发生态堪称"脱胎换骨"。当年主流的XML布局+Data Binding、Java主导开发的模式,早已被以Kotlin为核心、Jetpack Compose声明式UI为载体的现代开发体系所重塑。
本文将深度解析2017年后Android开发的核心变革,拆解现代技术栈,并通过实战demo与项目搭建教程,帮你快速衔接新时代的开发节奏。
一、核心变革:Android开发的"改朝换代"
2017年至今,Google通过推出MAD(Modern Android Development)理念,完成了从开发语言、UI构建到架构设计的全链路革新。其中最直观的变化,莫过于"告别XML"与"Kotlin优先"两大核心转变。
1.1 从XML到声明式UI:Jetpack Compose的颠覆
2017年前后,XML是Android布局的唯一主流选择,开发者需在XML中定义界面结构,再通过findViewById或Data Binding关联业务逻辑,不仅存在"布局与逻辑分离不彻底""控件更新繁琐"等问题,还需应对布局层级嵌套导致的性能损耗。
1.1.1 Jetpack Compose是什么
Jetpack Compose 是用于构建原生 Android 界面的新工具包。它使用更少的代码、强大的工具和直观的 Kotlin API,可以帮助开发者简化并加快 Android 界面开发。
在此之前,我们如何实现一个功能呢?我们是在Activity中编写Java/Kotlin的代码,在XML中编写布局代码,这种方式是我们已经使用了很久的方式,而Jetpack Compose完全抛弃了之前的方式,新创造了一种"使用代码"编写页面的方式,而这种方式,有一个好听的名字,叫做声明式UI。
Jetpack Compose作为Google推出的声明式UI工具包,彻底打破了这一模式------它允许开发者直接使用Kotlin代码描述UI,通过"状态驱动视图"的核心逻辑,实现UI的自动刷新与高效维护。无需再编写繁琐的XML文件,也无需手动绑定控件,开发效率与代码可读性大幅提升。
Google 推出的现代化 Android 声明式 UI 工具包,其首次公开时间为 2019 年,在当年的 Google I/O 大会上正式公布。2021 年 7 月:正式发布 1.0.0 稳定版本,可用于生产环境开发。

kotlin
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Compose01Theme {
// A surface container using the 'background' color from the theme
Surface(modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background) {
Greeting("Android")
}
}
}
}
}
@Composable
fun Greeting(name: String) {
Row() {
Text(text = "Hello $name!")
Text(text = "First Compose Demo",
modifier = Modifier
.padding(10.dp)
.background(Color.Red)
.clickable {
//click
})
}
}
@Composable
fun More(title:String) {
Row(modifier = Modifier
.background(Color.Red)
.padding(10.dp)
) {
Text(text = title,
fontSize = 16.sp, color = Color.White, modifier = Modifier.weight(1f)
)
Button(onClick = { }) {
Text(text = "查看详情", color = Color.White)
}
}
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
Compose01Theme {
Greeting("Android")
}
}
1.1.2 Jetpack Compose的革命性意义
Jetpack Compose的诞生标志着Android UI开发进入"声明式时代"。
相较于传统XML布局+View体系的命令式编程,Compose通过纯Kotlin代码实现UI描述,具有三大核心优势:
- 声明式UI模型:开发者只需描述"UI应该是什么样子",系统自动处理状态变化到UI更新的映射。例如实现一个计数器,传统方式需要findViewById后修改TextView内容,而Compose中只需声明
Text(count.toString()) ,状态变化会自动触发UI刷新。 - 组件化架构:每个Composable函数都是独立可复用的UI单元,支持嵌套组合。如 Button(onClick = { ... })
{ Text("Click me") } 将逻辑与UI无缝融合,避免了Fragment的复杂生命周期管理。 - 响应式数据流:通过 State 和 remember 实现数据驱动UI,配合 collectAsState
可轻松集成Flow/RxJava等响应式库。测试显示,Compose的列表渲染性能比RecyclerView提升30%以上(Google
I/O 2021数据)。
1.2 从Java到Kotlin:官方钦定的"第一语言"
2019年,Google正式宣布"Kotlin优先",标志着Java在Android开发中的主导地位被取代。尽管Java目前仍被支持,但所有新的Jetpack库、官方示例及新特性(如协程、Flow)均优先适配Kotlin。Kotlin的空安全特性的能大幅减少空指针崩溃,简洁的语法(如扩展函数、Lambda表达式)能显著减少模板代码,让开发者更专注于业务逻辑而非语法细节。
1.3 其他核心变革:异步、注入与架构的升级
除了语言与UI,异步处理、依赖注入与架构设计也发生了根本性变化:
-
异步处理:取代了复杂的AsyncTask与RxJava,协程(Coroutines)+ Flow成为主流,实现更简洁、可预测的异步编程;
-
依赖注入:Hilt作为基于Dagger 2的官方简化版本,成为标准化方案,无需手动编写繁琐的Dagger组件,实现依赖的自动注入;
-
架构设计:MVVM(Model-View-ViewModel)或MVI(Model-View-Intent)成为主流,配合ViewModel库实现数据持久化,与Compose完美适配。
二、现代Android开发技术栈(2026标准)
一个标准的现代Android项目,需围绕"Kotlin+Compose"构建全链路技术栈,以下是2026年行业主流的"黄金技术栈":
| 技术维度 | 推荐工具/库 | 核心作用 |
|---|---|---|
| 编程语言 | Kotlin | 空安全、简洁语法,官方优先支持 |
| UI框架 | Jetpack Compose(Material 3) | 声明式UI,支持动态配色与多设备适配 |
| 异步处理 | Coroutines + Flow | 异步编程与响应式流处理 |
| 依赖注入 | Hilt | 官方标准化DI方案,简化依赖管理 |
| 架构模式 | MVVM/MVI + Clean Architecture | 解耦逻辑与UI,提升可测试性 |
| 网络请求 | Retrofit + OkHttp | 行业标准的网络交互方案 |
| 本地存储 | Room + DataStore | SQLite抽象层,支持Flow衔接 |
| 工程化 | 多模块化 + Gradle Kotlin DSL | 提升编译速度与团队协作效率 |
三、实战Demo:新旧开发模式对比
下面通过"Hello World"与"登录页面"两个核心场景,直观对比2017年传统模式与现代模式的开发差异。
3.1 基础场景:Hello World
传统模式(XML + Java/Kotlin)
第一步:编写XML布局文件(activity_main.xml)
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textSize="20sp"/>
</LinearLayout>
第二步:在Activity中绑定并更新控件(MainActivity.kt)
kotlin
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 手动绑定控件
val textView = findViewById<TextView>(R.id.textView)
// 手动更新文本
textView.text = "Hello Modern Android!"
}
}
现代模式(Jetpack Compose + Kotlin)
无需XML文件,直接用Kotlin代码编写UI,通过Composable函数定义界面:
kotlin
// MainActivity.kt
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 直接在setContent中编写UI
setContent {
// 应用主题(Material 3)
MaterialTheme {
// 调用Composable函数
Greeting(name = "Modern Android")
}
}
}
}
// 声明式UI组件,可复用
@Composable
fun Greeting(name: String) {
// 类似函数调用的方式组合UI
Text(
text = "Hello $name!",
modifier = Modifier
.fillMaxSize()
.wrapContentSize(Alignment.Center),
fontSize = 20.sp
)
}
核心优势:无需维护XML与控件绑定,UI与逻辑在同一文件中,状态变化时Compose自动刷新文本。
3.2 核心场景:登录页面(现代模式完整实现)
基于MVVM架构+Compose+协程实现,包含状态管理、点击事件处理等核心功能。
第一步:定义UI状态类(LoginUiState.kt)
kotlin
// 存储登录页面的所有UI状态
data class LoginUiState(
val username: String = "",
val password: String = "",
val isLoading: Boolean = false,
val loginSuccess: Boolean = false,
val errorMsg: String? = null
)
第二步:实现ViewModel(LoginViewModel.kt)
kotlin
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
class LoginViewModel : ViewModel() {
// 私有可变状态流(仅ViewModel内部可修改)
private val _uiState = MutableStateFlow(LoginUiState())
// 公开不可变状态流(UI层仅可观察)
val uiState = _uiState.asStateFlow()
// 用户名输入变化回调
fun onUsernameChange(username: String) {
_uiState.value = _uiState.value.copy(username = username)
}
// 密码输入变化回调
fun onPasswordChange(password: String) {
_uiState.value = _uiState.value.copy(password = password)
}
// 登录按钮点击事件(协程处理异步逻辑)
fun onLoginClick() {
viewModelScope.launch {
// 1. 开始加载,清空错误信息
_uiState.value = _uiState.value.copy(
isLoading = true,
errorMsg = null,
loginSuccess = false
)
// 2. 模拟网络请求(异步操作)
delay(1500)
// 3. 验证与结果处理
val currentState = _uiState.value
if (currentState.username.isEmpty() || currentState.password.isEmpty()) {
_uiState.value = currentState.copy(
isLoading = false,
errorMsg = "用户名或密码不能为空"
)
} else {
_uiState.value = currentState.copy(
isLoading = false,
loginSuccess = true
)
}
}
}
}
第三步:实现Compose UI(LoginScreen.kt)
kotlin
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
@Composable
fun LoginScreen(
viewModel: LoginViewModel = viewModel(), // 自动注入ViewModel
onLoginSuccess: () -> Unit = {} // 登录成功回调
) {
// 观察ViewModel中的状态流,自动响应状态变化
val uiState by viewModel.uiState.collectAsState()
Column(
modifier = Modifier
.fillMaxSize()
.padding(24.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
// 用户名输入框
OutlinedTextField(
value = uiState.username,
onValueChange = { viewModel.onUsernameChange(it) },
label = { Text("用户名") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
// 密码输入框
OutlinedTextField(
value = uiState.password,
onValueChange = { viewModel.onPasswordChange(it) },
label = { Text("密码") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(24.dp))
// 登录按钮(加载状态时禁用并显示进度条)
Button(
onClick = { viewModel.onLoginClick() },
enabled = !uiState.isLoading,
modifier = Modifier.fillMaxWidth()
) {
if (uiState.isLoading) {
CircularProgressIndicator(
modifier = Modifier.height(24.dp).width(24.dp),
strokeWidth = 2.dp,
color = MaterialTheme.colorScheme.onPrimary
)
} else {
Text("登录")
}
}
// 错误信息提示
uiState.errorMsg?.let { errorMsg ->
Spacer(modifier = Modifier.height(16.dp))
Text(
text = errorMsg,
color = MaterialTheme.colorScheme.error
)
}
// 登录成功回调
if (uiState.loginSuccess) {
onLoginSuccess()
}
}
}
第四步:在Activity中使用LoginScreen
kotlin
@AndroidEntryPoint // Hilt依赖注入注解
class LoginActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
LoginScreen(
onLoginSuccess = {
// 登录成功,跳转首页
startActivity(Intent(this, HomeActivity::class.java))
finish()
}
)
}
}
}
}
四、新旧项目衔接:XML项目迁移到Compose
对于2017年前后的旧项目,无需推倒重来,Google提供了完善的互操作性方案,支持XML与Compose混合使用,实现平滑迁移。迁移可分为四个阶段逐步推进:
4.1 第一阶段:环境准备
在项目级与模块级build.gradle.kts中开启Compose支持并引入依赖(以Kotlin DSL为例):
kotlin
// 模块级build.gradle.kts
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}
android {
compileSdk = 35
buildFeatures {
compose = true // 开启Compose支持
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.x" // 需与Kotlin版本匹配
}
}
dependencies {
// Compose核心依赖
implementation(libs.compose.ui)
implementation(libs.compose.material3)
implementation(libs.compose.ui.tooling.preview)
debugImplementation(libs.compose.ui.tooling)
}
4.2 第二阶段:在XML中嵌入Compose(自下而上)
保留外层XML布局,将其中的单个子View(如按钮、卡片)替换为Compose组件,适合初次迁移尝试:
- 在XML中添加ComposeView占位符:
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 原有XML控件 -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="旧XML布局"/>
<!-- Compose占位符 -->
<androidx.compose.ui.platform.ComposeView
android:id="@+id/my_compose_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
- 在Activity/Fragment中渲染Compose内容:
kotlin
class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my)
val composeView = findViewById<ComposeView>(R.id.my_compose_view)
composeView.setContent {
// 渲染Compose组件
MyComposeButton(onClick = { /* 点击事件处理 */ })
}
}
}
// Compose组件
@Composable
fun MyComposeButton(onClick: () -> Unit) {
Button(onClick = onClick) {
Text("Compose按钮")
}
}
4.3 第三阶段:将整个页面迁移到Compose
当单个组件迁移稳定后,可直接移除XML文件,将整个页面替换为Compose实现:
kotlin
// Fragment示例(Activity类似)
class HomeFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// 直接返回ComposeView,无需加载XML
return ComposeView(requireContext()).apply {
setContent {
MaterialTheme {
HomeScreen() // 完整Compose页面
}
}
}
}
}
@Composable
fun HomeScreen() {
Column(modifier = Modifier.fillMaxSize()) {
Text("完整Compose页面")
// 其他Compose组件...
}
}
4.4 第四阶段:在Compose中复用旧XML View
若存在第三方库(如地图、旧版图表)暂无Compose版本,可通过AndroidView包裹旧View复用:
kotlin
@Composable
fun LegacyViewIntegration() {
AndroidView(
// 初始化旧View
factory = { context ->
TextView(context).apply {
text = "我是旧XML View"
textSize = 18f
}
},
// 状态变化时更新旧View
update = { view ->
view.text = "Compose状态驱动更新"
}
)
}
五、从零搭建现代Android项目(2026版)
搭建全新项目时,需遵循"多模块化+MAD架构"原则,以下是完整搭建流程:
5.1 项目创建(Android Studio)
-
打开Android Studio → File → New → New Project;
-
选择"Empty Compose Activity"模板(默认集成Compose,无XML布局);
-
配置参数:
-
Language:Kotlin(Compose仅支持Kotlin);
-
Minimum SDK:API 24+(推荐,兼容绝大多数设备,Compose最低支持API 21);
-
Build Configuration Language:Kotlin DSL(build.gradle.kts);
-
项目名称:ModernAndroidDemo。
-
5.2 项目结构设计(多模块化)
现代项目推荐多模块化结构,按功能与职责拆分模块,提升编译速度与可维护性,标准结构如下:
5.3 核心模块配置(关键代码)
1. 版本统一管理(gradle/libs.versions.toml)
bash
[versions]
kotlin = "2.2.20"
compose = "1.9.3"
compose-material = "1.4.0"
hilt = "2.57.2"
retrofit = "3.0.0"
room = "2.6.1"
[libraries]
# Compose
compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose" }
compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "compose-material" }
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" }
# Hilt
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }
# 网络
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
okhttp = { module = "com.squareup.okhttp3:okhttp", version = "4.12.0" }
# 本地存储
room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
2. 主模块配置(app/build.gradle.kts)
kotlin
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.dagger.hilt.android")
kotlin("kapt")
}
android {
namespace = "com.example.modernandroiddemo"
compileSdk = 35
defaultConfig {
applicationId = "com.example.modernandroiddemo"
minSdk = 24
targetSdk = 35
versionCode = 1
versionName = "1.0"
}
buildFeatures {
compose = true
viewBinding = false // 无需ViewBinding,Compose已替代
}
composeOptions {
kotlinCompilerExtensionVersion = libs.versions.compose.get()
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
// 核心依赖
implementation(libs.compose.ui)
implementation(libs.compose.material3)
debugImplementation(libs.compose.ui.tooling)
// Hilt
implementation(libs.hilt.android)
kapt(libs.hilt.compiler)
// 业务模块依赖
implementation(project(":feature:feature-login"))
implementation(project(":feature:feature-home"))
// 核心基础模块依赖
implementation(project(":core:core-common"))
implementation(project(":core:core-network"))
}
// Hilt注解处理器配置
kapt {
correctErrorTypes = true
}
3. 应用类配置(App.kt)
kotlin
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
// Hilt全局注入注解,必须在Application类上添加
@HiltAndroidApp
class App : Application() {
override fun onCreate() {
super.onCreate()
// 全局初始化操作(如日志、网络配置等)
}
}
4. 清单文件配置(AndroidManifest.xml)
xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.modernandroiddemo">
<application
android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ModernAndroidDemo">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
六、总结与进阶趋势
6.1 核心总结
2017年至今,Android开发的核心变革可概括为"三个转变":
-
开发语言:从Java主导到Kotlin优先,空安全与简洁性成为核心优势;
-
UI构建:从XML imperative布局到Compose声明式UI,状态驱动替代手动更新;
-
架构理念:从单一模块到多模块化+Clean Architecture,解耦与可维护性成为核心目标。
现代Android开发的终极标准栈可浓缩为:Kotlin + Jetpack Compose + Hilt + MVVM/MVI + 多模块化 + Gradle Kotlin DSL。
6.2 进阶趋势(2026+)
未来Android开发将向"跨平台"与"工程化深化"两大方向演进:
-
Kotlin Multiplatform(KMP):实现Android与iOS共享业务逻辑,甚至通过Compose Multiplatform共享UI,大幅降低跨平台开发成本;
-
AI辅助开发:Android Studio的AI功能(如Codey)将深度集成,自动生成Compose代码、优化布局与逻辑;
-
工程化升级:Buildless构建、动态功能模块(App Bundle)、CI/CD自动化将成为标准配置。
过去几年 Android 架构经历了从 MVC → MVP → MVVM → Clean Architecture 的演进。到了 2026 年,官方推荐的现代架构已经非常明确:
Kotlin + Jetpack Compose + Hilt + Clean Architecture + Gradle Kotlin DSL + 多模块化
这种结构不仅提升构建速度与维护性,还能让团队多人并行开发更加高效。
对于老开发者而言,无需恐惧变革------Compose与旧技术栈的互操作性、Google完善的迁移文档,都能让你平滑过渡。拥抱Kotlin与Compose,你将发现Android开发变得更简洁、更高效、更具乐趣。
参考链接
https://developer.android.com/codelabs/basic-android-kotlin-compose-first-app
https://blog.csdn.net/qq_42698421/article/details/153392719
https://blog.csdn.net/FDoubleman/article/details/156735424
https://blog.csdn.net/chenyiran123456/article/details/147026101
https://cloud.tencent.com/developer/article/2378444
https://developer.aliyun.com/article/1409238
https://github.com/compose-museum/WithCompose
https://developer.android.com/courses/android-basics-compose/course?hl=zh-cn