说到Android开发,很多人第一反应是“好难”、“语言多”、“配置繁琐”。但说实话,我刚入行那会儿也是这样想的。直到我自己动手跑通了第一个HelloWorld,那种成就感真的没法形容——就像你第一次亲手点亮了一盏灯。今天咱们不整那些虚的,我就当你是站在门口的那个好奇小孩,我牵着你,一步一步把这扇门推开,最后还能把整个房子盖起来。
先给你吃颗定心丸:现在的Android开发环境比五年前友好太多了。Google用Kotlin作为官方首选语言,Jetpack Compose让UI开发像搭积木一样简单,Android Studio更是直接集成了模拟器、性能分析、代码检查等全套工具。你只需要一台电脑(Windows、Mac、Linux都行),就能开启这段旅程。
第一站:把工具准备好
开发Android应用,核心工具只有一个:Android Studio。它是Google官方推出的集成开发环境(IDE),基于IntelliJ IDEA,专为Android设计。别被名字吓到,它其实很智能,会自动帮你下载依赖、配置环境变量。
下载安装很简单。去androidstudio.google.cn(国内镜像,速度快)或者直接去developer.android.com。下载完安装包,一路“下一步”就行。安装时,记得勾选“Android Virtual Device”(AVD),这是后面要用到的模拟器。
安装完成后,打开Android Studio,你会看到一个欢迎界面。第一次启动,它会问你要不要导入之前的设置,直接点“Do not import settings”就行。然后它会让你配置JDK(Java开发工具包),新版Android Studio自带JDK,所以直接点“Next”跳过即可。最后,它会让你选择UI主题,喜欢深色就选“Dark”,喜欢浅色就选“Light”,看个人喜好。
点“Finish”后,你就正式进入Android Studio的主界面了。这时候,你可能会有点懵——满屏幕的按钮和菜单,从哪下手?别急,我们先创建一个项目。
第二站:第一个应用HelloWorld
在Android Studio主界面,点击“Start a new Android Studio project”。接下来的一连串选项,是新手最容易卡住的地方。我来一步步教你怎么选。
1. 选择模板 第一个界面是“Select a Project Template”。这里有很多模板:Empty Activity、Chat Application、Gallery、Navigation Drawer Activity等。对于初学者,我们选最基础的Empty Activity。点击它,然后点“Next”。
2. 配置项目 接下来是“Configure your project”界面,这里有几个关键字段:
- Name: 项目名称,我建议你写
MyFirstApp,简单直接。 - Package name: 包名,这是应用的唯一标识。格式通常是
com.你的名字.应用名,比如com.agnes.myfirstapp。注意,包名一旦确定就不能改,所以想好点。用反域名格式最安全,比如com.example.myfirstapp。 - Save location: 项目保存路径,选一个你记得住的地方,比如
D:\AndroidProjects\MyFirstApp。 - Language: 语言选择。强烈建议选择Kotlin。Java虽然也能用,但Kotlin是Google力推的,代码更简洁,空指针安全,是现代Android开发的事实标准。
- Minimum SDK: 最低SDK版本。这是指你的应用能支持多老的Android版本。新手建议选API 24: Android 7.0 (Nougat)。这个版本覆盖了95%以上的活跃设备,而且API 24以下的系统已经非常少了,没必要为了那几百万用户增加复杂度。
选好后,点“Finish”。Android Studio会开始下载必要的依赖,这个过程可能需要几分钟,取决于你的网络。如果卡住,可以试试切换镜像源或者重启。
3. 理解项目结构 项目创建成功后,你会看到左侧的“Project”面板。默认显示的是“Android”视图,但这对于新手不太友好,因为很多文件被折叠了。建议切换到“Project Files”视图,这样你能看到真实的文件结构。
关键目录和文件如下:
MyFirstApp/
├── app/
│ ├── src/main/
│ │ ├── java/com/agnes/myfirstapp/
│ │ │ └── MainActivity.kt // 主Activity,应用的入口
│ │ ├── res/
│ │ │ ├── layout/
│ │ │ │ └── activity_main.xml // UI布局文件(XML方式)
│ │ │ ├── values/
│ │ │ │ ├── colors.xml // 颜色定义
│ │ │ │ ├── strings.xml // 字符串资源
│ │ │ │ └── themes.xml // 主题样式
│ │ │ └── mipmap-* // 图标资源
│ │ ├── AndroidManifest.xml // 应用清单,配置权限、组件等
│ │ └── res/drawable/ // 可绘制资源(图片、形状等)
│ ├── build.gradle.kts // 模块级构建脚本,定义依赖
│ └── proguard-rules.pro // 代码混淆规则
├── build.gradle.kts // 项目级构建脚本
├── settings.gradle.kts // 模块设置
└── gradle/ // Gradle Wrapper配置
别慌,我们一个一个看。
AndroidManifest.xml 是应用的“身份证”。它告诉系统这个应用叫什么名字、需要哪些权限、有哪些Activity等。打开它,你会看到:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.agnes.myfirstapp">
<application
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.MyFirstApp">
<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>
重点看<activity>部分。android:name=".MainActivity"指向我们的主Activity。<intent-filter>里的MAIN和LAUNCHER意味着这个Activity是应用的入口,点击图标时启动的就是它。
MainActivity.kt 是应用的“大脑”。打开它,你会看到:
package com.agnes.myfirstapp
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import com.agnes.myfirstapp.ui.theme.MyFirstAppTheme
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyFirstAppTheme {
Greeting("Android")
}
}
}
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
MyFirstAppTheme {
Greeting("Android")
}
}
}
这段代码用到了Jetpack Compose,这是Google推出的现代化UI toolkit。如果你之前做过iOS开发,会觉得它很像SwiftUI;如果你做过Web开发,会觉得它有点像React。核心思想是:UI是状态的函数,状态变化时,UI自动刷新。
setContent 是Composable函数的入口,告诉系统“这个Activity用Compose来构建UI”。Greeting 是一个简单的Composable函数,它接收一个字符串参数,然后显示出来。@Preview 注解让这段代码能在Android Studio的预览窗口中直接渲染,不用跑模拟器就能看到效果。
activity_main.xml 是传统XML布局文件。如果你选的是“Empty Activity (XML)”,你会看到这个文件。但新版模板默认用Compose,所以这个文件可能不存在,或者已经被弃用。我们这里先讲Compose,因为它是未来。
4. 运行你的第一个应用 现在,我们要让这个应用跑起来。有两种方式:模拟器和真机。
用模拟器: 在Android Studio顶部工具栏,找到设备选择下拉框(默认可能是“Pixel 3a”),点击它。如果列表为空,点“Create New Device”。选择“Phone”类别,挑一个你喜欢的手机型号(比如Pixel 6),点“Next”。然后选择系统镜像,推荐选“API 34: Android 14.0”的“x86_64”镜像(如果你用Intel/AMD CPU)或“arm64-v8a”镜像(如果你用Apple Silicon M系列芯片)。下载完镜像后,点“Finish”。
模拟器创建好后,点工具栏的“Run”按钮(绿色三角形),或者按 Shift + F10。Android Studio会编译项目,启动模拟器,然后安装并运行你的应用。
几秒钟后,模拟器屏幕亮起,你会看到一行字:“Hello Android!”。这就是你的第一个Android应用!
用真机: 如果你想用真机测试,步骤稍微多一步:
- 打开手机“设置” -> “关于手机”,连续点击“版本号”7次,开启“开发者选项”。
- 返回“设置” -> “系统” -> “开发者选项”,开启“USB调试”。
- 用数据线连接手机和电脑。首次连接时,手机会弹出“允许USB调试吗?”的提示,勾选“始终允许”,点“确定”。
- 在Android Studio的设备选择下拉框中,你应该能看到你的手机型号。选中它,点“Run”。
真机运行和模拟器效果一样,但更流畅,也能测试真实性能。
第三站:理解核心概念
HelloWorld跑通了,但你可能还是一头雾水:这到底是怎么工作的?为什么有点按钮就能跳页面?为什么UI能自动更新?我们来拆解几个核心概念。
1. Activity:屏幕的容器 Activity是Android应用的“页面”。每个Activity对应一个屏幕,用户看到的界面、进行的交互,都发生在一个Activity里。一个应用可以有多个Activity,比如登录页、主页、设置页,每个都是一个Activity。
Activity的生命周期是Android开发的基础。当你创建、启动、暂停、恢复、销毁一个Activity时,系统会回调一系列方法:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Activity被创建时调用,只调用一次
// 在这里初始化UI、绑定数据
setContentView(R.layout.activity_main) // XML方式
// 或 setContent { ... } // Compose方式
}
override fun onStart() {
super.onStart()
// Activity即将可见时调用
}
override fun onResume() {
super.onResume()
// Activity获得焦点,用户可与它交互时调用
}
override fun onPause() {
super.onPause()
// 系统准备启动另一个Activity时调用
}
override fun onStop() {
super.onStop()
// Activity完全不可见时调用
}
override fun onDestroy() {
super.onDestroy()
// Activity被销毁前调用
}
}
新手常犯的错误是在onDestroy里做耗时操作,或者在onPause里保存重要数据(因为系统可能不一定会调用onPause,而是直接杀进程)。正确的做法是用onSaveInstanceState来保存瞬态UI状态,用ViewModel来保存业务数据。
2. Intent:组件间的信使 Intent是Android中用于在组件之间传递消息的对象。它可以启动Activity、启动Service、发送Broadcast。
启动另一个Activity:
// 显式Intent:指定目标Activity
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("key", "value") // 传递数据
startActivity(intent)
// 隐式Intent:不指定目标,让系统匹配
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse("https://www.example.com")
startActivity(intent)
在第二个Activity中接收数据:
class SecondActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val value = intent.getStringExtra("key") ?: "default"
// 使用value
}
}
Intent还有startActivityForResult(已废弃,用Activity Result API替代)和sendBroadcast等用法,但新手阶段,掌握显式和隐式Intent就够用了。
3. View和Compose:UI的两种范式 传统Android UI用XML布局文件定义,代码逻辑写在Kotlin/Java里。这种方式直观,但容易碎片化——UI和业务逻辑分离,更新时需手动刷新。
Jetpack Compose是声明式UI框架,UI和逻辑写在同一个地方,用Kotlin代码描述UI结构。比如,一个简单的按钮:
Button(onClick = { /* 点击处理 */ }) {
Text("Click me")
}
是不是很像HTML?但Compose更强大,它能自动处理状态更新。当状态变化时,Compose只会重新绘制发生变化的部分,而不是整个页面。
对于新手,我建议先学Compose,因为它是趋势,而且代码更简洁。但也要了解XML,因为很多老项目还在用,而且理解底层原理有助于调试。
4. ViewModel:数据的守护者 ViewModel是Android Architecture Components的一部分,用于存储和管理UI相关的数据。它的核心特点是:生命周期感知。当Activity或Fragment因配置变更(如屏幕旋转)而重建时,ViewModel中的数据不会丢失。
用法:
class MyViewModel : ViewModel() {
private val _count = MutableLiveData(0)
val count: LiveData<Int> = _count
fun increment() {
_count.value = (_count.value ?: 0) + 1
}
}
class MainActivity : AppCompatActivity() {
private val viewModel: MyViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyFirstAppTheme {
val count by viewModel.count.observeAsState()
Column(modifier = Modifier.padding(16.dp)) {
Text(text = "Count: $count")
Button(onClick = { viewModel.increment() }) {
Text("Increment")
}
}
}
}
}
}
这里,_count是MutableLiveData,count是LiveData。observeAsState是Compose中观察LiveData的方式,当数据变化时,UI自动刷新。by viewModels()是委托属性,自动创建ViewModel实例。
5. Repository:数据的提供者 Repository是数据访问的抽象层,它整合多个数据源(本地数据库、网络API等),为ViewModel提供统一的数据接口。这样,ViewModel不需要关心数据从哪里来,只需要调用Repository的方法。
class MyRepository {
suspend fun fetchData(): Result<Data> {
// 从网络或数据库获取数据
}
}
第四站:搭建一个完整的小项目
光说不练假把式。我们来做一个稍微有点实际意义的小应用:待办事项列表(Todo List)。这个应用会用到Activity、ViewModel、Compose、本地存储等核心概念。
需求分析:
- 显示待办事项列表。
- 能添加新事项。
- 能删除已事项。
- 能标记事项为完成/未完成。
- 数据持久化,重启应用后数据不丢失。
步骤1:创建项目
按照前面的方法,创建一个新的Kotlin Compose项目,命名为TodoApp。包名用com.agnes.todoapp,最低SDK选24。
步骤2:设计数据模型
在data包下创建TodoItem.kt:
data class TodoItem(
val id: Long,
val title: String,
val completed: Boolean = false
)
步骤3:创建本地存储
用Room数据库,这是Google推荐的本地存储方案。先在build.gradle.kts中添加依赖:
dependencies {
val roomVersion = "2.6.1"
implementation("androidx.room:room-runtime:$roomVersion")
implementation("androidx.room:room-ktx:$roomVersion")
ksp("androidx.room:room-compiler:$roomVersion") // 需要安装KSP插件
}
然后创建实体类:
@Entity(tableName = "todo_items")
data class TodoItemEntity(
@PrimaryKey(autoGenerate = true)
val id: Long = 0,
val title: String,
val completed: Boolean = false
)
创建DAO(数据访问对象):
@Dao
interface TodoDao {
@Query("SELECT * FROM todo_items ORDER BY id DESC")
fun getAllTodos(): Flow<List<TodoItemEntity>>
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(todo: TodoItemEntity)
@Update
suspend fun update(todo: TodoItemEntity)
@Delete
suspend fun delete(todo: TodoItemEntity)
}
创建Database类:
@Database(entities = [TodoItemEntity::class], version = 1, exportSchema = false)
abstract class TodoDatabase : RoomDatabase() {
abstract fun todoDao(): TodoDao
companion object {
@Volatile
private var INSTANCE: TodoDatabase? = null
fun getDatabase(context: Context): TodoDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
TodoDatabase::class.java,
"todo_database"
).build()
INSTANCE = instance
instance
}
}
}
}
步骤4:创建Repository
在repository包下创建TodoRepository.kt:
”`kotlin class TodoRepository(private val dao: Todo
