
简介面向零基础或刚接触移动开发读者的 Android APP 入门教程资源定位清晰从 JDK、Android SDK 下载安装、开发环境搭建到 Eclipse/IntelliJ IDEA 中新建项目、编写 Hello Android 代码、完成 APK 打包手把手讲透第一条 Android 开发链路。教程为单份 PDF 文档压缩包大小仅 1.25MB文件类型单一便于下载后随时翻阅内容以实战为主线重点拆解 main.xml 界面布局、strings.xml 字符串资源以及 MyActivity.java 主程序的按钮点击与 Toast 交互等关键代码。已有 300 人浏览学习适合需要快速上手、想用最小成本了解 Android 开发全流程的初学者。相比零散网文这份资料将 SDK 配置、代码编写、打包发布等碎片信息整合成一个完整示例读者可循着教程完成自己的第一个可安装 APK从而建立对 Android 项目结构和开发环境的整体认知。1. 从 HelloAndroid 看 App 开发的最小闭环环境、代码、打包一个做过前端、和 Android/iOS 程序员配合过完整项目的人凌晨一点睡不着打开电脑写下人生第一个 Android 程序然后把整个流程整理成一篇教程。这个场景听起来很个人但它恰好覆盖了 Android App 开发最不能被跳过的三个环节环境搭建、代码编写、打包签名。这篇教程的价值不在代码有多复杂而在于它把「从零到能跑」的完整链路压缩在了一篇文章里而且默认你用的是 IntelliJ IDEA 这类通用 IDE不是被很多入门资料绑定死的特定环境。比起现在动辄教 Kotlin 协程、Jetpack Compose 的资料这篇基于原生 Java XML 布局的入门流程反而更容易让人看清 Android 应用的本质界面是布局文件定义的逻辑是 Activity 里的回调驱动的发布是一个签名后的 APK 文件。适合刚接触 Android、想快速跑通第一个真机程序的开发者也适合那些平时只写后端、想搞明白 App 构建流程的从业者。2. 先把工具链装齐JDK、Android SDK 与 IDE 的版本与配置Android 开发的第一步不是打开 IDE 写代码而是把 JDK、SDK、IDE 三者之间的版本关系理清楚。早期教程里这一步踩坑率最高而且报错信息往往不直接说「版本不匹配」而是给一个模糊的No JVM installation found或者 SDK 目录无法识别。这篇教程里的处理思路是先装 JDK 和 SDK再配置 IDE顺序上有讲究先有运行时再有工具链最后才有编译入口。2.1 JDK 与 ANDROID_HOME两个必须显式存在的路径JDK 是编译 Java 代码的基础Android SDK 是编译 Android 应用的基础。教程里特别提到一个问题SDK 安装时找不到 JDK 目录解决办法是在系统环境变量里添加JAVA_HOME路径指向 JDK 安装目录。这个问题的根源在于 Android SDK 的安装器本身是用 Java 写的它启动时需要找到一个可用的 JRE/JDK而 Windows 下靠的是注册表里的 Java 信息一旦 JDK 是解压版或者手动配置的注册表里没有记录就会出现找不到 JDK 的情况。# Windows 环境变量配置示例 JAVA_HOMEC:\Program Files\Java\jdk1.8.0_202 Path%JAVA_HOME%\bin;%Path% # Linux / macOS 环境下对应的写法 export JAVA_HOME/usr/lib/jvm/java-8-openjdk-amd64 export ANDROID_HOME$HOME/Android/Sdk export PATH$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools配置完成后在命令行执行java -version和adb version能正常输出版本号说明基础工具链已经通了。注意ANDROID_HOME这个变量在旧版工具链里不是强制项但很多第三方构建工具比如 Cordova、React Native 的旧版本依赖它建议从一开始就配好省得后面做混合开发时再回头补。2.2 SDK Manager 里的版本选择逻辑不是越高越好教程里建议把 Android 4.0 以上自己需要的版本都装上这个操作看起来是「多装无害」实际背后有一个编译版本和运行版本的匹配问题。SDK Manager 里能装的东西分几类SDK Platform对应某个 API Level 的系统库、Build-Tools编译打包工具、还有系统镜像跑模拟器用。如果只打算用真机调试只需要安装真机系统对应版本的 SDK Platform以及一个较新的 Build-Tools。表格里列出 API Level、系统版本与是否建议安装的对应关系方便按需选择组件类型对应内容安装建议用途SDK Platform对应 Android 系统版本的 API 库真机系统版本必须装编译时引用系统 APIBuild-ToolsAndroid SDK 构建工具装最新一个版本即可打包、资源编译、dex 转换Platform-Toolsadb、fastboot 等命令必须安装USB 连接与调试命令System Images模拟器系统镜像不用模拟器可不装启动 Android 模拟器这里的坑在于compileSdkVersion、minSdkVersion和targetSdkVersion三个概念。compileSdkVersion 只是决定编译时用哪个版本的 API不需要真机系统达到这个版本minSdkVersion 决定了应用最低支持到哪个系统低于这个版本的设备装不上targetSdkVersion 则影响系统对应用的特殊兼容行为。入门阶段最容易犯的错是把 compileSdkVersion 设成和真机系统一样的版本这会导致无法使用高版本 API反过来如果把 minSdkVersion 设得过高老设备直接无法安装。教程里说的「根据自己手机系统装对应版本 SDK 包」本质上是保证真机调试时系统版本不低于 minSdkVersion。2.3 IDE 里绑定 SDKNew 按钮背后的版本匹配机制教程使用的 IDE 是 IntelliJ IDEA配置原理与 Android Studio 完全相同。新建项目时选择 Android Application Module右侧 Project SDK 为空点击 New 按钮找到 SDK 目录下拉列表就能列出已安装的 SDK 版本。这一步要注意的是 SDK 目录的层级必须选择到包含 platforms、build-tools、platform-tools 三个子目录的那一层也就是 SDK 的根目录。选成 platforms 或 platform-tools 的上级目录都会导致 IDE 无法识别报错信息一般是「SDK location not found」或「Please choose a valid SDK directory」。正确选择到这一层 C:\Users\xxx\AppData\Local\Android\Sdk 错误的选择示例 C:\Users\xxx\AppData\Local\Android\Sdk\platforms C:\Users\xxx\AppData\Local\Android\Sdk\platform-tools如果第一次配置时 IDE 提示先设置 JDK直接按引导找到 JDK 安装目录即可这个顺序不能反。JDK 和 SDK 都就位后项目构建才能正常完成。IDE 会生成 App 名称对应的包名结构、res 资源目录、AndroidManifest.xml 等基础文件到这里环境准备才算真正结束。3. 看懂项目骨架布局文件、资源文件与主程序的职责划分新建项目完成后IDE 会在工程目录下生成一套标准的 Android 项目结构。很多入门教程直接让读者「把代码复制进 main.xml」但不解释这些文件之间的关系导致开发者在后续修改时完全不知道改哪里。这篇教程用 HelloAndroid 的代码把三个核心文件的职责讲清楚了main.xml 管界面长什么样strings.xml 管界面上显示的文本MyActivity.java 管交互逻辑。三个文件通过 R 类和资源 ID 串起来这是理解 Android 项目结构的关键。3.1 布局文件 main.xml界面结构的唯一来源main.xml 是 App 主窗体的布局文件它用 XML 的形式描述界面上的控件及其排列方式。里面的核心逻辑是LinearLayout作为根容器垂直排列一个TextView和一个Button。这个布局的代码量不大但涉及了几个入门阶段必须掌握的属性?xml version1.0 encodingutf-8? LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/android android:orientationvertical android:layout_widthfill_parent android:layout_heightfill_parent TextView android:layout_widthfill_parent android:layout_height180dp android:textstring/default_message android:idid/hellotextView android:textColor#00ff00 android:gravitycenter/ Button android:layout_widthwrap_content android:layout_heightwrap_content android:textstring/button_send android:idid/hellobutton android:layout_gravitycenter/ /LinearLayout布局文件里值得细看的是string/default_message和id/hellobutton这两种引用写法。string/前缀表示引用 strings.xml 里定义的字符串资源好处是文案修改不需要动布局文件id/前缀表示新增一个资源 ID后续 Java 代码里通过R.id.hellobutton来引用这个控件。两个控件的高度设置用了不同单位TextView 写的是180dpButton 写的是wrap_content。dp 是密度无关像素保证在不同屏幕密度的设备上物理尺寸一致wrap_content 表示控件大小由内容决定这是入门阶段最容易忽略的单位问题用 px 或 sp 不当会造成界面在不同手机上展现效果差异极大。3.2 strings.xml 与 i18n 思想文案和逻辑分离的起点strings.xml 在教程里被描述为「i18n 文件」这个说法虽然不完全准确严格说它只是资源本地化的一部分但方向是对的。把界面上的所有字符串都抽到资源文件里而不是硬编码在布局或代码中意味着后期做多语言版本时只需要增加对应的 values-en、values-zh-rTW 等目录不需要改动任何 Java 代码逻辑。?xml version1.0 encodingutf-8? resources string nameapp_namehelloandroid by hiwanz/string string namebutton_sendSay something/string string namedefault_messageClick button below!/string string nameinteract_messageYou just clicked on the Button!/string /resources这里定义了一个默认文案default_message是按钮未被点击时 TextView 的初始文本interact_message是点击按钮后 TextView 要切换成的文本。这种「界面上显示的内容全部由资源文件提供」的做法在团队协作中尤其重要后端的同学只需要关注逻辑文案修改可以交给运营或前端同学直接在资源文件里改不会冲突到代码文件。后续如果做多语言只需要在同一 key 下替换不同语言的 value。3.3 MyActivity.java界面和逻辑之间的桥MyActivity 继承自 ActivityonCreate方法在 Activity 创建时被系统调用setContentView(R.layout.main)把 main.xml 定义的布局加载到窗口中。findViewById方法的本质是遍历视图树找到指定 ID 对应的控件实例拿到 Button 实例后通过setOnClickListener注册点击事件的回调。这套流程概括起来就是「加载布局、找到控件、注册事件、更新界面」后面所有 Android 页面开发不管多复杂核心都是这四个步骤的变体。package com.example.helloandroid; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MyActivity extends Activity { Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }注意onCreate方法里的savedInstanceState参数它用于 Activity 被系统销毁重建时恢复状态。入门阶段不需要深入理解但需要知道这个回调是 Activity 生命周期的一部分后面做复杂页面时要接触完整的生命周期方法链onStart、onResume、onPause、onStop、onDestroy。4. 事件响应与 APK 打包从按钮点击到签名发布前两章完成了环境搭建和项目结构认知这一章解决两件事点击事件如何真正改变界面内容以及写完的代码如何变成可安装的 APK 文件。事件响应是 Android 应用的「交互引擎」打包则是从开发态到发布态的必经门槛这两个环节理解透了从一个空工程到一个能装的 App对你来说就没有盲区了。4.1 点击事件绑定匿名内部类与控件实例的获取点击事件的处理方式是这章的核心它遵循典型的「获取控件实例 → 设置监听器 → 在回调中更新界面」模式。这里的重点是View.OnClickListener这个接口的使用方式package com.example.helloandroid; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MyActivity extends Activity { Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取布局中 id 为 hellobutton 的按钮实例 Button hellobtn (Button) findViewById(R.id.hellobutton); // 注册点击事件监听器参数是一个匿名内部类 hellobtn.setOnClickListener(new View.OnClickListener() { Override public void onClick(View v) { // 获取 TextView 实例准备更新其显示内容 TextView hellotv (TextView) findViewById(R.id.hellotextView); // 弹出短时 Toast 提示参数依次为上下文环境、提示文本、显示时长 Toast.makeText(MyActivity.this, Clicked, Toast.LENGTH_SHORT).show(); // 使用资源 ID 直接设置文本内容等价于 getString(R.string.interact_message) hellotv.setText(R.string.interact_message); } }); } }代码里有几个细节要解释。findViewById被调用了两次一次在onCreate里获取 Button一次在onClick回调里获取 TextView。现实中更好的做法是在onCreate里把两个控件都获取好存入成员变量或局部变量中因为findViewById需要遍历视图树频繁调用会有性能损耗尤其复杂布局时更明显。setText(R.string.interact_message)直接把资源 ID 传给setText系统会先解析资源 ID 对应的字符串再设置到控件上。Toast.makeText的第一个参数传入MyActivity.this因为匿名内部类内部的this指向的是View.OnClickListener实例要引用外部 Activity 必须用类名限定这是 Java 内部类语法中常见的坑。4.2 真机调试USB 调试开关与 adb 连接的先决条件写完代码后在 IDE 里直接点击 RunIDE 会自动完成编译、打包、安装、启动整个流程。但前提是电脑能识别到手机这依赖几个条件手机上开启 USB 调试模式、电脑端安装对应的 USB 驱动、USB 连接模式选择为「文件传输」而不是「仅充电」。教程里提到「手机系统设置里的开发人员选项里打开 USB 调试」这是 Android 4.2 以后系统默认隐藏开发者选项需要连续点击「关于手机」里的版本号 7 次才能解锁这个入口。从命令行验证设备连接状态# 查看当前已连接的 Android 设备 adb devices # 期望输出中显示设备序列号与 device 状态 # List of devices attached # 0123456789ABCDEF device如果输出显示unauthorized说明手机屏幕上弹出了 USB 调试授权请求需要点击允许如果显示offline一般是 adb 版本和手机不兼容升级 platform-tools 可以解决如果完全没有设备优先检查 USB 驱动。注意adb devices输出里的 device 状态是连接成功的标志不是前面的序列号。4.3 生成签名 APKKeyStore 与签名文件的完整流程应用开发完成后要打包发布IDE 的 Build 菜单里选择Generate Signed APK这个操作的背后是 Android 应用签名机制的完整链路。签名的作用不是加密而是标识应用作者身份系统通过签名判断应用是否被篡改、是否能覆盖安装。签名文件KeyStore包含一对公钥和私钥私钥由开发者保管用它对 APK 做摘要签名系统安装时用公钥验证签名。在Generate Signed APK向导中如果还没有 KeyStore点击Create New新建需要填写的字段包括字段作用填写建议Key store path签名文件保存位置必须妥善备份丢失后无法再更新已发布的应用Password签名文件密码与 Key password 一致或分开均合法但需要记住Alias密钥别名区分同一个签名文件中的多个密钥默认用项目名即可Validity (years)密钥有效期建议 25 年以上应用签名有效期不能短于应用可能的更新周期First and Last Name / Organization组织信息CN、OU、O 等可以不填或随便填实际发布时这些信息出现在证书里填完并点击 OK 后IDE 会用这个 KeyStore 对 APK 进行签名编译完成后在 Destination APK path 指定的目录下生成helloandroid.apk。这一步生成的 APK 用的是 release 签名可以直接发布到应用市场也可以直接传输到手机上安装。Debug 模式下 IDE 会用默认的 debug.keystore 自动签名这也是为什么开发时无需手动配置签名就能安装运行的原因但 debug 签名的应用无法发布到应用商店。5. 真机部署与定向排错USB 调试、logcat 与最小兼容策略最后一章处理所有入门者几乎都会撞上的实际问题代码没问题但真机装不上、跑不了、或者效果与预期不符。这一章的定位是「可复用的排错手段」从连接、安装与运行验证三个角度出发。5.1 安装失败的典型原因与 adb install 手动验证IDE 一键 Run 失败时报错信息往往覆盖了真正的安装细节使用 adb 命令手动安装可以获得更直接的回显。先把 APK 输出到本地目录然后执行adb install -r app-debug.apk如果输出Success说明 APK 本身没问题问题出在 IDE 与设备连接环节如果出现INSTALL_FAILED_UPDATE_INCOMPATIBLE说明手机已经安装了同包名的 debug 版本应用需要先卸载旧的如果出现INSTALL_FAILED_INSUFFICIENT_STORAGE则清理设备存储空间后重试。-r参数表示允许覆盖安装测试阶段通常会用到。5.2 logcat让崩溃原因直接输出到命令行代码抛异常导致应用闪退时IDE 的 Logcat 窗口和命令行 adb logcat 的输出内容一致但命令行过滤更灵活适合批量搜集日志定位问题的场景# 清除屏幕上的旧日志然后显示 AndroidRuntime 相关异常同时过滤当前应用进程 pid adb logcat -c adb logcat AndroidRuntime:E *:S-c先清空缓冲区避免混淆旧日志AndroidRuntime:E表示只显示 AndroidRuntime 标签下 Error 及以上级别的日志*:S将其他所有标签静默。闪退时最常见的崩溃信息是FATAL EXCEPTION: main后面跟随完整的异常堆栈通常可以在最顶部找到具体是哪个文件的哪一行抛出了异常。5.3 多机型兼容的最小调试策略不同品牌 Android 设备与 ROM 在 USB 调试、权限管理、后台限制上的差异是真实开发中比代码本身更耗时间的问题。入门阶段先把目标限定在自己的主力测试机上保证以下条件全部满足开发者选项开启、USB 调试打开、插线时选择「传输文件」模式而非「仅充电」。出现device unauthorized时先拔掉数据线在手机上撤销 USB 调试授权重新插入再授权一次。如果连接不稳定更换数据线比更换电脑更有效很多 USB 调试失败的实际原因只是线缆不支持数据传输。本文还有配套的精品资源点击获取