1. 第一篇入门笔记,我打算先解决什么问题
先说句实在话:安卓开发入门这个方向,网上的资料多到让人反而不知道怎么下手。官方文档太全太散,视频教程追着版本跑,论坛里的回答又经常默认你已经知道了一堆前置概念。我自己当年从零开始摸这条路的时候,最痛苦的不是某个API不会用,而是根本搞不清楚“我应该先学什么、学到什么程度算会了”。所以这份学习笔记,我打算换个思路来写——不按官方文档的目录顺序走,而是按一个新手实际动手时“会碰到什么、会卡在哪里”的顺序来组织。
这篇是第一篇,目标很明确:从零开始,把第一个能跑的安卓应用做出来,并且真正搞懂它为什么能跑。我会把环境准备、新建项目、目录结构、界面控件的起步用法、调试工具这五块串起来讲,每一步都会解释“为什么要这么做、不这么做会怎样”。这份笔记适合完全没接触过安卓开发的人,也适合学过一点但始终没形成完整认知的朋友——你不需要提前精通Java或Kotlin,只要会基本的编程概念,能跟着操作,就能把地基打起来。
安卓开发入门,难就难在它不像写普通的小脚本,写完一跑就出结果。它有一套自己的工程结构、构建流程、运行机制,光是把“代码是怎么变成手机上那个App的”这件事理解清楚,就能劝退不少人。但也正因为门槛存在,一旦你把第一套流程完整走通,后面学什么都有底气。这篇笔记就是想帮你把这道坎迈过去。
2. 环境准备和第一个Demo项目:很多人放弃在这里
2.1 开发工具的选型,和安装前的几个判断
做安卓开发,官方推荐的工具就是Android Studio。这一点没什么悬念,也不用纠结什么“用别的编辑器行不行”——行,但没必要。Android Studio是基于IDEA开发的集成开发环境,它把代码编辑、资源管理、构建打包、模拟器、调试工具全部集成在一起。对新手来说,省去自己拼装工具链的麻烦,比“轻量”重要得多。
安装之前,有几个判断要自己做:
第一,电脑配置。Android Studio本身不算太吃配置,但Android模拟器很吃。如果你手里的电脑内存低于8G,建议直接用真机调试,别在模拟器上较劲。我自己早期用一台8G内存的轻薄本跑模拟器,启动一次要五分钟,运行起来卡到怀疑人生,后来换真机瞬间舒坦。这个选择会在后面详细说。
第二,网络问题。SDK和Gradle依赖的下载是新手最常见的隐形坎。安装完Android Studio后,首次创建项目会下载一大堆依赖,这个过程在网络不理想的时候会非常折磨人。解决方案有两个:一是配置国内镜像源,二是提前把常用依赖下载好。具体配置方法网上一搜就有,但我要提醒的是——别在下载依赖这一步失去耐心,这是所有新手都经历过的事,不是你电脑坏了。
第三,安装的版本选择。建议直接装稳定版,别碰Beta或Canary版本。我之前用过一个预览版,结果插件不兼容、构建报错,浪费了一整个晚上排查,最后发现只是版本本身的bug。入门阶段,稳定压倒一切。
2.2 新建项目时那一堆选项,到底要不要改
安装完成后,第一次打开Android Studio会有一个欢迎页,选“New Project”就会进入新建项目的向导界面。这页面上的选项很多,新手很容易慌。我逐个说一下该怎么选。
首先是项目模板。向导会把模板分成Phone和Tablet、Wear OS、Automotive等几大类。入门阶段,什么都别多想,直接选“Empty Views Activity”这个模板。注意,这里有两个看起来很接近的选项——一个是“Empty Activity”,一个是“Empty Views Activity”。早期的Android Studio用的是“Empty Activity”,它基于新的Compose UI框架;而“Empty Views Activity”用的是传统的View系统加XML布局。对于学习入门来说,选“Empty Views Activity”更合适。原因后面讲界面控件时会细说,简单说就是:传统XML布局的资料更多、出错更容易排查,先把这套吃透了再去碰Compose不迟。
然后是项目信息的填写。几个字段里最重要的是“Package name”,也就是应用包名,它相当于应用的唯一身份证号。默认会基于你的公司域名生成,比如“com.example.myapplication”。新手随便填一个就行,但要注意全小写、不能有中文或空格。这里不决定你以后的生死,因为以后想改也能改,只是越早定下来越省事。
Language的选择上,现在默认是Kotlin,建议选Kotlin。我不建议从Java入门,虽然老一辈教程很多用Java,但Kotlin现在已经成了安卓开发的主流语言,语法更简洁,空安全设计能帮你挡掉很多运行时的崩溃问题。别觉得“多学一门语言”是负担——Kotlin本身不难,入门阶段你只需要用到它的基本语法,比你想的简单。Minimum SDK这个选项,默认选API 24左右就行,太低会增加你处理兼容性的负担,太高会影响覆盖的设备范围。新手用默认值就好,这个以后随时能调整。
2.3 第一个Hello World跑起来之后,先别急着高兴
项目创建完成后,Android Studio会自动进行Gradle同步。第一次同步通常会持续几分钟到十几分钟,取决于你的网络状况。同步完成后,你会看到一个标准的项目结构,代码编辑区里打开了一个叫做MainActivity.kt的文件,内容大概是这样:
package com.example.myapplication import android.os.Bundle import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContentView(R.layout.activity_main) } }这段代码现在可能看得一头雾水,但你只需要先抓住一个关键:setContentView(R.layout.activity_main)这行,它的意思是“把activity_main.xml这个布局文件设置为当前界面的内容”。也就是说,你看到的界面长什么样,是由XML布局文件决定的;而Activity则是承载界面的“容器”。这两者的关系,建议从现在就刻在脑子里——后面所有的界面开发都围绕它转。
接下来运行这个项目。Android Studio的工具栏上有一个绿色的运行按钮,点击后它会问你选择运行设备。如果你有安卓手机,用USB连上电脑,开启手机的“开发者选项”和“USB调试”,就能在设备列表里看到它;如果你没有真机,就选一个模拟器设备来创建。这里我要特别说一句:能用真机尽量用真机。模拟器对新手来说多了一层配置和性能的坑,真机的体验更接近实际用户看到的效果。等以后需要测试不同尺寸屏幕时再研究模拟器不迟。
第一次运行,如果你是新手,大概率会卡几下:要么是Gradle在后台默默下载东西,要么是手机驱动没识别到,要么是“跑起来了但界面还在加载”。这些都很正常。当我第一次在手机上看到那个显示“Hello Android!”的界面亮起来的时候,说实话那种“代码真的变成了一个App”的感觉,是后面学再多API都取代不了的。但我要提醒的是——先别急着欢呼,这个Demo本身还没什么含金量,真正的挑战从读懂项目结构开始。
3. 拆解新建项目里的每个角落:目录结构不是背出来的
3.1 两个build.gradle文件,分别管什么
一个新建的安卓项目,最让新手困惑的往往是这个:为什么有两个build.gradle文件?一个在项目根目录,一个在app模块目录里。这背后其实是安卓工程的一个基本设计思想——多模块构建。
根目录那个build.gradle只负责声明所有模块共用的配置,比如仓库源和插件版本。它更像一个“总调度员”,自己不怎么干活,但规定着大家用什么工具版本。而app/build.gradle才是真正操心你这个App怎么编的:依赖了哪些库、最低支持什么版本的安卓系统、应用编号是什么、启用的构建类型有哪些。举一个我踩过的例子:想给项目加一个网络请求库,网上教程让你在dependencies里加一行代码,如果你不看清楚加进了哪个文件,就会陷入“明明照着做了却一直报错”的窘境。
这里面还有个概念叫Gradle。你可以把它理解成安卓项目的“建造机器”——它按照build.gradle里的配方,把Java/Kotlin代码、XML资源、图片、第三方库全部打包在一起,最终生成一个APK安装包。新手容易忽略Gradle的另一个角色:它还是个依赖管理器。你所有的第三方库声明,都由它去拉取和整合。所以那些“加了一行依赖,然后整个项目同步报错”的情况,十有八九是版本冲突或网络问题。
建议你现在就做一件事:把这俩build.gradle文件分别打开,逐行看一遍,遇到不懂的配置项就上网搜一下是什么意思。花这半小时很值,因为以后几乎所有技术文章里的操作,都会提到“修改build.gradle”。
3.2 AndroidManifest.xml是应用的“户口本”
每个安卓项目都有一个AndroidManifest.xml文件,放在app/src/main目录下。我管它叫“户口本”,因为应用的所有“身份信息”都登记在这里:它的包名是什么、有哪些页面(Activity)、能响应哪些系统事件、需要申请哪些权限。
新手最常见的一个问题就是从网上找了一个代码示例,照着写了个新页面,一运行就崩溃,Logcat里报“ActivityNotFound”。原因大概率就是:新页面没有在AndroidManifest.xml里登记。所有你创建的界面Activity,都必须在这个文件里声明,就像员工入职必须登记在册,否则系统根本不知道有这个东西存在。
文件里另一个容易遇到的概念是intent-filter。新建项目自带的MainActivity里就有一个:
<intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter>这两行的意思是:这个Activity是应用的入口,并且会出现在手机桌面启动器上。没有它,你的应用装上之后桌面连图标都没有。理解了这个,以后你写多页面跳转、处理外部链接等场景时,就不会被AndroidManifest弄得一头雾水。
3.3 res目录下那些文件夹,放错位置就会出问题
res目录是安卓项目的资源仓库,所有界面布局、图片、字符串、颜色都按类型放在子目录里。布局文件放在layout文件夹,图片放在drawable文件夹,应用名称和所有硬编码字符串放在values文件夹中的strings.xml里。
新手比较容易懵的是,drawable文件夹经常有好几个后缀版本,比如drawable-v24、drawable-hdpi。这是安卓为不同操作系统版本和不同屏幕密度准备的“适配方案”——同一张图标你可能要准备多套尺寸,系统按设备的实际情况挑最合适的那套。入门阶段你不用担心全部细节,只需要记住一个原则:文件名要全小写,不能有特殊字符,资源文件按类型放对目录。我曾经因为把一个图片放到了values目录里,构建直接报错,检查了半天才发现只是放错位置。这类错误没有任何技术含量,就是经验问题。
values文件夹里还有个strings.xml值得一提。安卓强烈建议你所有文案都写在这里,而不是直接写在布局或代码里。这样做的原因一是多语言适配方便,二是代码干净。举个例子,你的按钮文字如果不写在strings.xml里,以后想做英文版就得去代码里一个一个找;写在里面的话,只需要加一个values-en文件夹的翻译文件就行。新手阶段可以不强求,但这个习惯建议早点养成。
4. 从按钮开始认识界面控件:事件机制是入门第一道分水岭
4.1 布局文件和Activity是怎么“绑定”在一起的
刚才说到了setContentView(R.layout.activity_main)这行代码,现在可以稍微深入一点。打开activity_main.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"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_text" /> </LinearLayout>这是一个极简的界面:一个显示文字的TextView,一个按钮Button,外面包着一个LinearLayout。layout_width="match_parent"表示宽度填满父容器,wrap_content表示“内容多大我多大”。android:id给控件取了个名字,方便在代码里找到它。
“绑定”这个概念,新手第一次遇到时会觉得抽象。本质上就是两步:第一,在XML里给控件设置id;第二,在Activity代码中用findViewById(或者更现代的viewBinding)通过这个id找到控件对象,之后你就能在代码里操控它了。你可以把XML理解成“画图纸”,Activity代码理解成“施工和运营团队”——图纸画出界面的样子,代码让界面活起来、响应操作。
setContentView的作用就是“把这张图纸拿过来用”。所以整个流程的逻辑链条是:Activity被创建时,系统调用onCreate,onCreate里用setContentView加载布局文件展示界面——就这么简单。这个认知,是后面所有界面开发的基础。
4.2 给按钮写点击事件,几种写法各有什么优劣
控件放上去了,接下来第一件想做的事大概率就是“点击按钮,发生点什么”。这就是事件机制。点击事件在安卓里是最基础也最重要的交互逻辑。
最经典、在教程里最常见的写法是:
button.setOnClickListener { textView.text = "你点击了按钮" }一行代码搞定。它做了什么?setOnClickListener这个方法接收一个“点击时干什么”的动作,花括号里就是你要执行的代码。在Kotlin里这种写法很顺手,适合绝大多数场景,也是我推荐新手优先掌握的方式。
还有一种老式的写法是让Activity本身实现View.OnClickListener接口,然后在onClick方法里用when分支处理不同控件的点击。这种写法在控件不多的时候很清晰,但控件一多就会让代码臃肿。再有一种是XML里直接写android:onClick="方法名",看着很方便,但在代码里查找方法、维护重构时都不方便,而且调试时少了一层可观测性,我不太推荐新手用。
这里的核心知识不是一个写法,而是背后的事件分发机制:用户在屏幕上点了一下,系统把这个触摸事件打包,层层分发,最终落到具体控件上,控件判断点击区域命中后,触发对应的监听器方法。理解了“点击事件是一整套从系统到控件的传递链路”,你就不会在面对复杂手势时发怵了。
4.3 LinearLayout和dp单位,早懂早省钱
布局文件里最常见的LinearLayout,它的核心属性是orientation——方向。vertical是垂直排列,从上往下排;horizontal是水平排列,从左往右排。新手容易忽略的是layout_weight权重属性,这个是LinearLayout的精华:它能够让子控件按比例分配剩余空间。比如两个按钮各设layout_weight="1",它们就会平均分占父容器的宽度;一个设1一个设2,就是1:2的比例。这个技巧在做一个简单的登录界面时非常实用,两行输入框加一个按钮,用线性布局加权重就能排得很好看,不需要复杂的嵌套。
再一个绕不开的概念是单位。安卓里布局尺寸常用的有dp、sp、px。px是像素点,不同的手机屏幕密度不同,同一个px在不同设备上看到的实际大小不一样。dp是密度无关像素,它屏蔽了屏幕密度差异,保证在不同设备上视觉大小基本一致。而sp是专门给字体用的,它会跟随用户系统的字体缩放设置变化,照顾不同视力需求的用户。入门阶段你只要记住:间距尺寸用dp,字体大小用sp,永远别直接用px就对了。
我早期踩过一个很典型的坑,就是清一色用px写了一个外表看起来挺正常的布局,结果换了一台高分辨率手机测试,界面直接“缩”成一团。其实原因很简单,px在高密度屏上会被等比放大,但dp不会。这个知识点如果没人跟你说,自己排查往往要花不少时间。
5. Logcat和调试:第一门必须掌握的硬功夫
5.1 为什么说Logcat比System.out好用
很多刚学编程的人习惯用System.out.println打印信息看程序执行情况,这在普通Java程序里没什么问题,但在安卓开发里不够用。安卓有自己的日志系统——Logcat,它把应用运行时产生的所有日志按级别和标签分类,统一输出到Android Studio的Logcat窗口里。
Logcat的用法很简单:
import android.util.Log private val TAG = "MainActivity" Log.d(TAG, "onCreate执行了") Log.e(TAG, "这里出错了:${exception.message}")Log.d是调试级别,Log.e是错误级别。它好在哪?第一,你可以在日志里加标签(TAG),方便按模块过滤;第二,日志级别清晰,排查问题的时候能直接过滤出错误;第三,Logcat还带了线程信息和时间戳,能帮你判断代码执行顺序和耗时。
新手学调试,第一步就是学会看Logcat。很多人遇到App崩溃就慌了,其实崩溃时Logcat里会有一长串红色的错误日志,其中最关键的通常是那一行FATAL EXCEPTION,下面跟着的Caused by会直接告诉你崩溃发生在哪个文件和哪一行。学会了看这行信息,你排查问题的效率至少提升一倍。遇到一个报错,先别急着百度错误全文,先自己把Logcat里的关键行读懂,很多时候问题自己就解决了。
5.2 断点调试的基本操作
除了打日志,断点调试是另一门必修功。它的原理很简单:在代码某一行设置一个“暂停点”,程序运行到这里就停下来,这时候你可以查看所有变量的当前值,也可以一行一行往下执行,观察代码的状态变化。
在Android Studio里操作就三步:在代码行号旁边点一下,出现一个红点;正常运行App;程序停住后,调试面板里会显示调用栈和变量值。你可以用“Step Over”按钮(快捷键F8)逐行执行当前方法,用“Step Into”(F7)跳进方法内部看实现。思路和之前写普通程序调试完全一致。
断点调试最大的价值不是“看哪里报错”,而是“看代码到底怎么走的”。很多逻辑Bug,你觉得某段代码应该执行,但实际情况它压根没走;你觉得某个变量值应该是123,实际它是null。断点一停下来,这些猜测瞬间变成眼见为实。我建议新手在入门阶段就养成一个习惯:遇到逻辑问题,第一反应是开断点看状态,而不是靠猜或者反复加日志。日志和断点配合使用,才是完整的调试姿势。
6. 我在初学阶段踩过的坑,和调整后的学习路线
6.1 最容易耽误进度的三个认知误区
第一个误区是“先把Kotlin语法学完再动手写App”。这个想法不能说全错,但代价巨大。我见过太多人花了几个星期在语法书上学习“协程”“泛型”这些高级特性,还没写过一个界面就烦了。对于安卓入门,你真正需要的Kotlin语法其实非常少:变量声明、函数定义、空安全的基础、lambda的基本使用,四五个小时就能覆盖。边做项目边补语法,效率远高于先啃完语法书。先跑起一个App,获得正反馈,比什么都重要。
第二个误区是“代码报错说明我做错了,我得从头找解决方案引到的完整代码”。要纠正这个心态:报错不是失败信号,而是系统在给你反馈。安卓开发涉及的链条太长——Gradle版本、SDK版本、依赖冲突、系统API差异,任何一环都可能出现警告或报错。遇到报错,先看清错误信息,按从近到远的顺序排查,实在不行再搜索。把“报错”当成日常交流的一部分,而不是“洪水猛兽”,你的学习体验会好很多。
第三个误区是“等我把所有知识点都学会了再开始做自己的App”。这个想法很容易让人一直停留在“学习中”的状态,永远下不了手。我的建议是:哪怕你的第一个App只是个界面难看、逻辑简单的计数器,也值得把它完整做出来并装到自己手机上。因为在这个过程中你才会遇到真问题,而不是“想象中的问题”。做项目和看教程的差别,就像学游泳和看游泳教学视频的差别——后者看一百遍,下水还是会慌。
6.2 如果你也是零基础,下一步建议先做什么
这篇笔记讲到了环境搭建、Project结构、布局、控件、日志和调试,算是把“跑通第一个App”这条主线路打通了。我建议你在往下学之前,先做一个不是很难的小练习:做一个简单的应用,界面上有一个输入框和一个按钮,点击按钮后把输入框的文字显示到下方文本里。别小看这个练习,它至少覆盖了布局编写、控件获取、事件监听、状态显示这四个高频知识点。你独立做完它,对“布局文件加Activity代码”这个协作模式就会有真实的体感。
做完了这个小练习,下一步的路线可以这样排:先学会写一个简单的多页面应用,在Activity之间跳转并传递数据(Intent和Bundle);接着学列表类界面的实现(RecyclerView),这是绝大多数App界面的基础形态;然后是网络请求,从最简单的HttpURLConnection开始理解原理,再过渡到Retrofit这类主流库;最后是数据存储,了解SharedPreferences和数据库的基本用法。这样一条线走下来,你基本就能做出一个有登录、有列表、有接口请求的完整小应用了。
学习笔记的第一篇,就先讲到这里。现在回头看这一篇的内容:环境准备、第一个Demo、项目目录深度拆解、控件基础、调试入门——它们之间的顺序,是我按“新手会在哪一步失去耐心”这个标准调整过的。写这一篇笔记我自己也重新走了一遍流程,最大的体会是:初学安卓,真正的对手不是某个高深的API,而是信息密度太大导致的混乱感。所以哪怕这一篇里有些概念你暂时用不上,也建议至少“混个脸熟”——等以后在具体项目里再遇到它们,你会觉得比第一次见亲切很多。下一篇我会接着写“Inten与多页面跳转”,到时候我们继续把一个能看能点的App,一步一步做完整。