ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Android App开发基础入门:环境配置、项目结构、界面、存储与打包上架

Android App开发基础入门:环境配置、项目结构、界面、存储与打包上架 1. 从零上手 Android App 开发基础先把认知框架立起来1.1 为什么很多人卡在装完 Android Studio 就不知道干嘛我带过几个刚入行的朋友几乎所有人都经历过同一个尴尬期Android Studio 装好了SDK 下完了新建项目能跑起来然后就停了。屏幕上一个Hello World接下来该往哪走完全没头绪。这不是能力问题是学习路径没搭好。Android App 开发基础这件事本质上要解决三个层次的问题工具链怎么配、代码往哪写、写完怎么变成能装到手机上的东西。这三层缺一层后面都会反复回来补课。我见过有人写了半年业务代码还是搞不清 Gradle 和 SDK 的关系一遇到同步失败就只能重装 IDE这种状态做项目会很痛苦。这篇文章我打算按真实的动手顺序来拆从环境配置讲到项目结构从界面绘制讲到数据存储最后到签名打包。适合完全零基础想入门的人也适合写了点代码但知识是碎的、想系统补一遍的人。核心关键词就是Android、App、开发基础我尽量把每一步的为什么这么做讲清楚而不是只丢命令给你抄。提醒网上流传的很多所谓一键配置脚本汉化破解包我劝你直接跳过。IDE 和 SDK 的完整性一旦被破坏后面报的错会让你怀疑人生而且这类来源不明的包本身就有风险。1.2 一套能落地的知识地图长什么样我习惯把 Android 开发基础拆成五块按依赖关系排环境层Android Studio、JDK、Android SDK、Gradle这四样版本必须互相匹配结构层Module、Gradle 脚本、Manifest、资源目录搞清楚文件放哪界面层XML 布局或 Compose、Activity/Fragment 生命周期、常用控件数据层SharedPreferences、文件、SQLite/Room、网络请求交付层调试、签名、打包、上架很多人一上来就冲着做个 App 赚钱去跳过了结构层和生命周期结果写出来的界面一切屏就崩、内存泄漏一片。基础这东西省下来的时间后面都要加倍还回去。我个人建议的学习节奏是第一周只干环境加结构把新建项目的每个文件都点开看一遍第二周啃界面和生命周期手动写一个能跳转的多页面 App第三周开始碰数据和网络。这个节奏不快但每一步都踩实。2. 环境搭建把工具链一次配到位少走三天弯路2.1 Android Studio 安装与版本选择的关键考量Android Studio 是官方 IDE基于 IntelliJ IDEA 社区版定制。现在官网提供 Windows、macOS、Linux 三端安装包还有 Apple Silicon 原生版本。这里有个坑Mac 用户千万别下错架构M 系列芯片要选 arm64 版本装了 x86 版本靠 Rosetta 转译跑IDE 会明显卡顿Gradle 编译速度也会掉一截。下载渠道我只推荐官网第三方绿色版精简版看着省事实际砍掉了 SDK Manager、AVD Manager 这些东西后面你要装个模拟器镜像都找不到入口。安装过程本身没什么难度一路下一步即可但有两个选项值得留意安装选项建议原因Android Virtual Device勾选需要模拟器调试时不用再单独装安装类型 Standard / Custom新手选 Standard自动匹配 SDK 路径和 JDK省去版本对齐的麻烦关于Android Studio 怎么设置中文这个问题搜索量一直很高。官方从 2020.3 版本开始支持语言包插件操作是Settings → Plugins → Marketplace搜索Chinese (Simplified) Language Pack安装后重启。注意插件版本要和 IDE 大版本对应装错版本会提示不兼容。我的真实建议是新手可以先用中文过渡一到两周但尽早换回英文。原因很直接——你搜到的报错信息、官方文档、Stack Overflow 上的回答全是英文中文界面里对照着找菜单项反而增加一层翻译成本。等你熟悉了菜单位置英文界面并不会更难。2.2 首次启动的配置SDK、JDK 与 Gradle 的版本对齐第一次启动 IDE会弹出 SDK 下载向导。这里要下的东西主要有Platform SDK对应某个 API Level、Build-Tools、Platform-Tools内含 adb、Emulator 和系统镜像。现在 Google 对上架应用有 targetSdk 的硬性要求所以至少装两个平台版本一个最新的用来开发一个稍旧的用来兼容测试。只装最新版的话遇到老项目打开会提示缺 SDK。JDK 这块是最容易出事的地方。我列一下当前主流版本的对应关系这个表是我踩坑之后整理的AGP 版本需要的 JDKGradle 版本范围8.0 及以上JDK 178.0 - 8.x7.4JDK 11 或 177.5 - 7.67.0 - 7.3JDK 117.0 - 7.4Android Studio 自带一个 JetBrains RuntimeJBR大多数情况下用内置的就行。但如果你在命令行执行./gradlew报 JDK 版本不匹配就需要在Settings → Build → Build Tools → Gradle里手动指定 Gradle JDK 路径。Gradle 版本不要去手改gradle-wrapper.properties里的 distributionUrl除非你清楚自己在做什么。正确的做法是改build.gradle里的 AGP 版本IDE 会提示你同步对应的 Gradle 版本。强行错配的结果就是一堆看不懂的NoSuchMethodError。注意国内网络环境下Gradle 首次同步经常卡在下载依赖上。可以在项目级build.gradle里换成国内镜像源但换之前先确认镜像同步了你要用的库版本否则会出现依赖找不到的假报错。2.3 模拟器与真机调试怎么选模拟器好处是方便坏处是吃内存。我的配置是给模拟器分配 2GB 内存、4GB 存储开硬件加速Windows 上是 HAXM 或 Hyper-VMac 上默认走 Hypervisor Framework。但涉及蓝牙、传感器、性能、相机这类功能必须上真机。模拟器的蓝牙是虚拟的连着 ESP32 这类硬件调试根本跑不通。真机调试要开启开发者选项里的 USB 调试连上后adb devices能看到设备序列号才算成功。真机连不上是高频问题排查顺序我固定用这套换数据线很多线只能充电不能传数据手机通知栏看看有没有USB 用途选项切成传输文件撤销 USB 调试授权后重新插拔Windows 上检查设备管理器有没有带感叹号的驱动需要装厂商 USB 驱动3. 项目结构拆解一个 App 目录里到底放了什么3.1 Module、Gradle 脚本与目录职责新建一个项目默认会生成app这个 Module。整个工程目录里真正需要你天天打交道的其实就几个地方app/src/main/java或 kotlin源码app/src/main/res资源包括布局、图片、字符串、颜色app/src/main/AndroidManifest.xml应用清单注册组件、声明权限app/build.gradle当前 Module 的构建配置build.gradle项目级全局配置一般只放插件版本gradle/libs.versions.toml新版模板里的版本目录统一管理依赖版本AndroidManifest.xml值得单独说。它相当于 App 的户口本四大组件必须在这里注册否则运行时直接抛ActivityNotFoundException。权限也是在这里声明但声明不等于授予危险权限还需要运行时动态申请。build.gradle里的compileSdk、minSdk、targetSdk三个参数新手最常搞混compileSdk用哪个版本的 SDK 编译决定你能调用哪些新 APIminSdk最低支持到哪个安卓版本决定你的用户覆盖面targetSdk告诉系统你适配到了哪个版本影响系统的兼容行为minSdk每降低一个版本兼容成本就上升一截。现在做新项目我一般定在 24Android 7.0或 26Android 8.0再往下就要处理一堆老 API 的兼容分支性价比不高。3.2 四大组件到底是什么关系Android 四大组件分别是 Activity、Service、BroadcastReceiver、ContentProvider。用生活场景类比一下Activity是你看到的每一个页面比如首页、详情页、设置页。它负责跟用户交互有完整的生命周期。Service是后台干活的没有界面。比如播放音乐、上传文件。现在后台限制越来越严长时间后台任务建议用 WorkManager。BroadcastReceiver是广播接收器比如监听开机完成、网络变化。它本身很轻量不能做耗时操作。ContentProvider是跨应用共享数据的标准接口。你可能见过形如content://com.xxx.fileprovider/external_path/...这样的 URI这就是通过 ContentProvider 暴露出来的资源地址。它的结构是content://授权标识/路径/具体文件系统通过授权标识找到对应应用注册的 Provider。这个机制的意义在于应用之间不能直接读彼此私有目录的文件必须通过 ContentProvider 这个窗口来交换数据。文件共享场景下通常配合 FileProvider 使用把应用私有目录下的文件映射成一个可对外传递的 URI。理解这一点你才能明白为什么直接传file://路径给别的应用会抛FileUriExposedException。3.3 资源体系与多设备适配res目录下的资源命名规则很严格只能小写字母、数字和下划线不能有大写字母和中文。这条规则违反的话编译期直接报错。常见的资源目录和它们的适配用途目录用途适配维度layout布局文件横竖屏、屏幕尺寸drawable图片、形状密度values字符串、颜色、尺寸语言、主题、深色模式mipmap应用图标密度多语言适配就是在values旁边建values-en、values-zh-rCN这样的目录里面放同名strings.xml。系统会根据设备语言自动挑选。深色模式同理建values-night。屏幕适配有个密度概念要讲清楚dp是密度无关像素sp是缩放无关像素用于字体。布局尺寸一律用 dp文字一律用 sp直接写px会导致不同手机上显示大小天差地别。这个规则看着简单但我在代码审查里见过太多次写死的 px 值。4. 界面开发从布局文件到第一个能跑的页面4.1 布局写法与 ConstraintLayout 的取舍布局方式有两套传统的 XML 和现代的 Jetpack Compose。两者现在并行新项目我倾向 Compose但XML 仍然要会看因为存量项目绝大多数是 XML。XML 布局的几种容器按使用频率排ConstraintLayout约束布局复杂界面的首选能减少嵌套层级LinearLayout线性布局简单的横竖排列FrameLayout帧布局层叠效果RecyclerView列表不属于容器但界面里离不开ConstraintLayout 的核心思想是每个控件通过约束关系确定位置而不是靠层层嵌套。嵌套层级越深测量和绘制耗时越长复杂列表里这个差异很明显。上面提到的协调布局CoordinatorLayout通常配合AppBarLayout和CollapsingToolbarLayout使用能做出标题栏随滚动折叠的效果。轮播图Banner一般用ViewPager2加适配器实现或者用成熟的三方库。这里我不建议自己从零撸轮播指示器、自动播放、生命周期管理这些细节坑很多。布局文件示例一个带文本和按钮的简单页面?xml version1.0 encodingutf-8? androidx.constraintlayout.widget.ConstraintLayout xmlns:androidhttp://schemas.android.com/apk/res/android xmlns:apphttp://schemas.android.com/apk/res-auto android:layout_widthmatch_parent android:layout_heightmatch_parent TextView android:idid/tvTitle android:layout_widthwrap_content android:layout_heightwrap_content android:textstring/app_name android:textSize20sp app:layout_constraintTop_toTopOfparent app:layout_constraintStart_toStartOfparent app:layout_constraintEnd_toEndOfparent android:layout_marginTop48dp / Button android:idid/btnStart android:layout_widthwrap_content android:layout_heightwrap_content android:textstring/start app:layout_constraintTop_toBottomOfid/tvTitle app:layout_constraintStart_toStartOfparent app:layout_constraintEnd_toEndOfparent android:layout_marginTop24dp / /androidx.constraintlayout.widget.ConstraintLayout注意app:layout_constraintXXX这些属性少了约束控件就会跑到左上角。这是新手最常见的布局问题。4.2 进度条、图标与常用控件实操进度条在 Android 里分两种水平进度条展示百分比进度和圆形进度条表示加载中。XML 里用ProgressBar通过style属性切换形态!-- 圆形加载中 -- ProgressBar android:idid/pbLoading android:layout_width48dp android:layout_height48dp android:indeterminatetrue style?android:attr/progressBarStyle / !-- 水平进度 -- ProgressBar android:idid/pbDownload android:layout_widthmatch_parent android:layout_heightwrap_content android:max100 style?android:attr/progressBarStyleHorizontal /代码里更新进度就一行binding.pbDownload.progress 50。但千万别在主线程做耗时操作再更新进度界面会卡死。正确姿势是子线程跑任务通过 Handler 或协程切回主线程更新 UI。关于应用图标和动态图标主题现在 Android 支持自适应图标Adaptive Icon用前景层和背景层两个 drawable 组合。动态图标比如时钟 App 的图标跟着时间变需要用到ActivityManager的别名机制配置在 Manifest 里还受桌面启动器支持情况限制不是所有设备都能生效。控件这块还有一个高频需求是字体设置。全局字体可以通过主题里指定fontFamily单控件用android:fontFamily。要引入自定义字体文件放在res/font目录下然后引用。4.3 Activity 生命周期与页面跳转生命周期是 Android 界面的核心概念七个回调方法onCreate → onStart → onResume → onPause → onStop → onDestroy ↑ | └──── onRestart ─────┘每个方法的职责我用一句话概括onCreate初始化setContentView 在这里绑定数据onStart界面可见但不可交互onResume界面可见可交互适合启动动画、注册监听onPause失去焦点保存关键数据执行要快onStop完全不可见释放重量级资源onDestroy销毁取消所有异步任务和监听onRestart从停止状态回到前台内存泄漏大部分源于生命周期没配对。比如在onCreate里注册了广播接收器却忘了在onDestroy里注销再比如静态变量持有了 Activity 引用。这类问题在开发期看不出来跑久了就 OOM。页面跳转用 Intentval intent Intent(this, DetailActivity::class.java) intent.putExtra(id, 1001) startActivity(intent)从 Android 11 开始包可见性收紧了如果你要查询别的应用能不能响应某个 Intent需要在 Manifest 里声明queries否则查询结果永远是空。5. 数据存储与权限机制App 怎么把数据留住5.1 四种存储方式的选型逻辑Android 提供四类本地存储选哪个取决于数据形态存储方式适合场景数据量级是否结构化SharedPreferences配置项、开关状态小键值对内部文件日志、缓存文件中无Room 数据库列表数据、关系数据大是DataStore替代 SharedPreferences小键值对或对象SharedPreferences 用起来最简单但有两个坑一是它加载时会一次性把整个文件读进内存存大字符串会拖慢启动二是它的apply()是异步写、commit()是同步写在主线程用 commit 会有卡顿风险。现在官方推荐用 DataStore 替代支持协程和 Flow异步安全。Room 是 SQLite 的封装用注解定义实体和 DAO编译期就能检查 SQL 语法。文件存储则是通过context.filesDir或context.getExternalFilesDir()拿到路径后者在应用卸载时会被一并清除。提示应用私有目录/data/data/包名/下的文件其他应用无权访问。想要跨应用共享要么走 ContentProvider要么申请存储权限写到公共目录。5.2 权限申请的完整流程从 Android 6.0 开始危险权限需要运行时申请。分类上权限分普通权限安装即授予和危险权限需要动态申请。危险权限按组划分同组内授予一个其他自动授予。申请流程分三步Manifest 里声明uses-permission运行时判断checkSelfPermission是否已授予未授予则requestPermissions发起请求在onRequestPermissionsResult里处理结果几个容易翻车的点用户勾选不再询问后再调 requestPermissions 会直接回调拒绝此时应引导用户去设置页Android 11 之后有了仅本次允许选项位置权限返回的可能是近似位置存储权限在 Android 13 之后拆成了READ_MEDIA_IMAGES、READ_MEDIA_VIDEO、READ_MEDIA_AUDIO三个关于 Android 的存储权限演变我整理了一张对照表放在问题排查章节这里先记一个原则能用系统文件选择器SAF解决的就别申请全盘存储权限用户更愿意给审核也更宽松。5.3 网络请求与数据解析App 的数据大多来自后端网络层是绕不开的。主流方案是 OkHttp 做底层、Retrofit 做接口封装、Gson 或 Moshi 做 JSON 解析。Retrofit 的基本用法interface ApiService { GET(user/profile) suspend fun getProfile(Query(uid) uid: Long): ApiResponseUser }配合协程在 ViewModel 里调用异常处理用 try-catch 包起来。网络请求必须放在子线程Android 3.0 之后主线程做网络操作会直接抛NetworkOnMainThreadException。还有一点从较新版本开始默认的 HTTP 明文请求被禁用。如果你的后端还是 http需要在network_security_config.xml里显式放行或者干脆让后端升到 HTTPS。这个配置也是后面讲抓包失败时的关键。6. 调试、签名与打包上架从代码到能装的 APK6.1 ADB 常用命令与日志排查ADBAndroid Debug Bridge是调试的核心工具几个高频命令# 查看连接设备 adb devices # 查看日志按标签过滤 adb logcat -s MyApp:D # 安装 APK adb install -r app-debug.apk # 清除应用数据 adb shell pm clear com.example.myapp # 抓取崩溃日志到文件 adb logcat -b crash crash.log日志级别从低到高是V D I W E FE是 ErrorF是 Fatal。排查崩溃时优先看E和F再结合异常堆栈定位。adb还有一个很实用的能力是拉起 Activityadb shell am start -n com.example.myapp/.MainActivity测试深层页面跳转时很省事不用一层层点进去。另外还有adb shell dumpsys系列能查看内存、Activity 栈、电量等运行状态定位性能问题时很有用。6.2 应用签名与 SHA1 获取调试版本用的是 IDE 自动生成的 debug keystore正式发布必须用自己的签名文件。签名的作用是证明这个 App 是我发的防止被篡改。签名一旦丢了应用就无法更新只能换包名重新上架所以 keystore 文件一定要备份密码一定要记住。生成签名文件keytool -genkeypair -v -keystore myrelease.jks -keyalg RSA -keysize 2048 -validity 36500 -alias mykey查看签名信息包括 SHA1 值keytool -list -v -keystore myrelease.jks -alias mykeySHA1 值做什么用接入第三方服务时经常要填比如地图 SDK、推送服务、微信登录。它相当于签名的指纹。这里有个坑开发阶段用的 debug 签名和发布签名算出来的 SHA1 不一样接入时必须两个都填上否则调试正常、上线后接口全部失败。在 Gradle 里配置签名推荐把密码放在keystore.properties里并加入.gitignore不要硬编码在构建脚本中signingConfigs { release { storeFile file(keystoreProps[storeFile]) storePassword keystoreProps[storePassword] keyAlias keystoreProps[keyAlias] keyPassword keystoreProps[keyPassword] } }6.3 打包上架的成本与流程开发一个 App 并上架大概要多少钱这个问题问的人特别多我把真实成本拆一下。直接成本Google Play 开发者账号是一次性 25 美元。国内安卓应用市场大多免费但需要企业资质或软件著作权证书软著代办通常几百元官方渠道也支持自行申请。间接成本服务器、域名、短信验证码、对象存储这些做个小工具 App 每月几十元起步做网约车、运动社交这类带实时定位和消息推送的服务器成本会明显上。时间成本从开发到上架顺利的话两三周遇到审核驳回可能反复。国内审核常见驳回原因包括隐私政策不完整、权限申请理由不充分、无对应资质等。上架流程的核心步骤生成签名 APK 或 AABGoogle Play 强制 AAB 格式准备应用图标、截图、描述文案、隐私政策链接填写内容分级问卷、目标受众、数据安全表单提交审核等待通过如果是内部测试或小范围分发直接用 APK 文件分发即可没必要走完整上架流程。iOS 那边还有浏览器唤起安装 App这类企业签名分发的场景但这类方式合规风险高不建议用于正式产品。7. 常见问题排查实录这些年踩过的坑7.1 环境与构建类问题速查现象可能原因处理方式Gradle 同步卡住依赖源访问慢换镜像源或配置本地缓存提示 JDK 版本不兼容Gradle JDK 与实际不符Settings 里手动指定 Gradle JDK项目移植后打不开SDK 路径、AGP 版本不一致统一 AGP 与 Gradle 版本重下 SDK编译报资源重复三方库资源冲突在 build.gradle 里加 resourcePrefix 或排除策略IDE 索引异常缓存损坏File → Invalidate Caches 后重启项目移植是个高频场景从同事那拷过来或者从仓库拉下来第一件事应该是看gradle-wrapper.properties里的 Gradle 版本、项目级build.gradle里的 AGP 版本、以及local.properties里的 SDK 路径。这三样对齐了八成问题就没了。7.2 编译与运行时报错排查app is not defined这类报错在前端混编场景下很常见通常是脚本加载顺序问题或者变量作用域没对上。Android 原生开发里类似的坑是 R 文件找不到一般为资源命名不合法或引用了错误包名的 R。启动就崩溃第一件事看logcat的红色部分重点找Caused by。常见原因有空指针Kotlin 里检查可空类型Java 里加判空未注册组件忘了在 Manifest 注册 Activity依赖缺失使用了某个库但没加依赖ProGuard 混淆release 包正常是因为混淆规则配错了debug 不混淆所以没暴露混淆这块要多说一句接入反射、序列化的地方必须加 keep 规则否则 release 包会莫名崩溃而 debug 完全正常这种问题排查起来最费时间。7.3 网络调试类问题抓包失败怎么办抓包失败是排查接口问题时最常见的障碍原因基本绕不开这几类第一类是证书信任问题。从 Android 7.0 开始应用默认不信任用户安装的证书只信任系统证书。所以即使你在手机上装了抓包工具的证书App 的请求还是不经过代理。解决办法是配置network_security_config.xml对调试域名显式信任用户证书network-security-config domain-config cleartextTrafficPermittedtrue domain includeSubdomainstrue你的调试域名/domain trust-anchors certificates srcuser / certificates srcsystem / /trust-anchors /domain-config /network-security-config第二类是 SSL Pinning。应用在代码里内置了证书指纹代理证书直接不匹配。这类需要改代码去掉校验但仅限于你自己负责的应用别人的应用不要尝试。第三类是 HTTP/2 或 QUIC 协议。部分抓包工具对这两种协议支持不好可以在抓包配置里禁用强制降级到 HTTP/1.1。注意抓包只应该用于调试自己开发或有明确授权的应用涉及他人数据的操作要合规评估这条线不能碰。另外提醒一句调试期间把network_security_config配好了发布前一定要把明文放行的配置去掉或收紧否则是明显的安全隐患应用市场审核也可能因此驳回。8. 学习路线上的一点个人体会Android 的入行门槛其实不算高但知识面的宽度是真的宽。我自己的经验是别一开始就想着把整条链路吃透那会直接劝退。比较务实的做法是找一个小而完整的目标练手比如一个运动记录 App——本地记录步数、列表展示历史、详情页看图把 Activity 跳转、Room 存储、RecyclerView、权限申请这些基础串一遍。做完这个你会发现前面那些零散的知识点自动连成了一张网。关于零基础开发学习路线这类问题我的答案一直很直接先能跑再能改最后能设计。第一阶段不追求架构漂亮能出个功能完整的 Demo 就行第二阶段开始读别人的源码改改三方库的默认行为第三阶段才谈模块化、组件化、架构分层这些。最后分享一个小习惯我会专门建一个snippets目录把每次解决掉的报错和对应的修复方案记成一行文本比如Gradle 同步报 JDK 不匹配 → 换 Gradle JDK 到 17。攒到两三百条之后遇到问题基本能做到条件反射式定位这比任何教程都管用。
返回列表