一、运行方式
1.运行 (Run)
当您选择“运行”时,Android Studio 会编译您的应用并将其安装到目标设备或模拟器上。这通常用于:
快速部署: 您只想看看应用是否能正常启动并运行,或者进行一些基础的用户界面测试。
性能测试: 在正常运行模式下测试应用的实际性能。
发布版本: 模拟用户实际使用应用时的环境。
在运行模式下,虽然您可以看到应用的输出日志(Logcat),但您无法在代码执行过程中暂停、检查变量或逐步跟踪代码的执行路径。它更像是一个“黑盒”测试,您只能根据应用的外部表现来判断其行为。
2.调试运行 (Debug Run)
当您选择“调试运行”时,Android Studio 会以调试模式编译并部署您的应用。这意味着它会启用额外的工具和功能,让您可以对代码的执行过程进行精细的控制和深入的检查。调试运行主要用于:
问题排查: 当您的应用出现错误、崩溃或行为异常时,调试是定位问题的最有效方法。
理解代码逻辑: 逐步跟踪代码,了解不同变量的值如何变化,以及代码的执行流程。
验证假设: 在特定条件下验证您的代码是否按照预期工作。
在调试模式下,您拥有以下强大的功能:
断点 (Breakpoints): 您可以在代码的任何行设置断点。当程序执行到断点时,会自动暂停。
单步执行 (Step Over, Step Into, Step Out):
- Step Over: 执行当前行代码,如果当前行有方法调用,则直接执行完该方法,不进入方法内部。
- Step Into: 执行当前行代码,如果当前行有方法调用,则进入该方法内部的第一行。
- Step Out: 从当前方法内部跳出,执行完当前方法剩余的代码,并返回到调用该方法的地方。
变量检查 (Variables): 在程序暂停在断点时,您可以查看当前作用域内所有变量的实时值。
表达式求值 (Evaluate Expression): 您可以即时执行代码片段或计算表达式的值,以测试不同的逻辑或查看复杂对象的状态。
调用栈 (Call Stack): 查看当前代码执行的调用路径,了解是哪个函数调用了当前的函数。
3.installDebug
是什么运行方式?
installDebug
并不是一个直接的“运行方式”,而是 Gradle 中的一个任务 (Task),用于将您的 Android 应用的 debug (调试) 版本安装到连接的设备或模拟器上。
在 Android Studio 中,当您点击“调试运行”按钮时,幕后执行的一系列操作中就包含了 installDebug
这个 Gradle 任务。它通常涉及以下步骤:
编译 Debug 版本: Gradle 会编译您的应用代码和资源,生成一个带有调试信息的
.apk
文件。这个.apk
文件包含了调试器需要的所有信息,以便您可以在代码中设置断点、检查变量等。签名 Debug 版本: 这个
.apk
文件会使用一个特殊的调试密钥库进行签名。安装到设备/模拟器: 编译和签名完成后,
installDebug
任务会将这个.apk
文件安装到您当前连接的 Android 设备或正在运行的模拟器上。
总结来说,installDebug
是构建和安装应用调试版本的一个自动化步骤,它是您在 Android Studio 中进行调试的基础。 您通常不需要直接调用这个任务,Android Studio 会在您执行调试操作时自动处理。
与 installRelease
任务相对,后者用于构建和安装发布 (release) 版本的应用,通常不包含调试信息,并使用您的发布密钥库签名,适用于最终用户发布。
4.为什么会产生“运行 installDebug
后才能使用 appDebug
发生变化”的错觉?
Android 项目的构建由 Gradle 负责。Gradle 通过一系列的 任务 (Tasks) 来完成从源代码到最终 APK 的整个过程。
installDebug
和 appDebug
(或类似的运行/调试任务,例如 runDebug
或通过 IDE 的运行按钮触发的) 都是 Gradle 任务。
installDebug
任务: 这个任务的主要职责是将 Debug 构建类型 的 APK 文件安装到连接的设备或模拟器上。它不负责编译或打包代码。它只是将已经构建好的 APK 推送到设备。appDebug
(或 IDE 运行/调试) 任务: 当你点击 Android Studio 中的“运行”或“调试”按钮时,IDE 会触发一系列的 Gradle 任务。这些任务通常包括:
- 编译 (Compile): 将你的 Java/Kotlin 代码、资源文件等编译成 DEX 文件和打包资源。
- 打包 (Package): 将编译后的文件和资源打包成 APK 文件。
- 安装 (Install): 将生成的 APK 文件安装到设备或模拟器上。
- 启动 (Launch): 启动应用程序的主 Activity。
并且Gradle 拥有强大的 构建缓存 (Build Cache) 和 增量编译 (Incremental Compilation) 机制。这是造成“错觉”的关键因素之一。
构建缓存: Gradle 会缓存之前构建的输出,如果输入没有改变,它就不会重新执行某个任务,而是直接使用缓存的结果。这意味着如果你只更改了代码中的一小部分,Gradle 不会重新编译整个项目。
增量编译: 增量编译进一步优化了编译过程,它只编译那些发生变化的源文件,而不是重新编译所有文件。
现在,我们可以解释为什么你会产生“运行 installDebug
后才能使用 appDebug
发生变化”的错觉:
- IDE 行为和“运行”按钮的简化: 当你在 Android Studio 中点击“运行”或“调试”按钮时,IDE 实际上会为你执行一个完整的“构建、安装、运行”流程。这个流程内部包含了编译、打包和安装等多个步骤。
installDebug
的直接性: 当你手动运行installDebug
任务时,你仅仅是告诉 Gradle 去安装 当前设备上已存在的、最新构建的 Debug APK。如果你之前已经通过 IDE 运行过项目(触发了完整的构建流程),那么installDebug
只是把那个已经构建好的 APK 重新安装了一遍。- 未触发完整构建: 真正的“变化”需要代码被 重新编译和打包。如果你只是在修改代码后,直接运行
installDebug
而没有先进行一次完整的构建(通过 IDE 的运行按钮或者手动执行assembleDebug
等任务),那么installDebug
安装的仍然是旧版本的 APK,因为你的代码更改还没有被编译进新的 APK 中。 - 构建系统优化: 在大多数情况下,当你修改代码并点击“运行”时,Android Studio 会智能地检测到代码变化,并触发必要的编译和打包任务。这意味着即使你觉得你只是“运行”了
appDebug
,实际上整个构建流程已经悄悄地在后台为你完成了。如果你没有看到变化,很可能是因为你的更改未能正确触发重编译,或者缓存导致了旧代码的加载。
“运行 installDebug
后才能使用 appDebug
发生变化”的说法是错误的。真正的变化来源于 代码的重新编译和打包,而 installDebug
仅仅是负责将 已构建好的 APK 安装到设备上。
当你修改代码后,要确保你的更改生效,你需要:
通过 Android Studio 的“运行”或“调试”按钮重新运行应用。 这是最常见和推荐的方式,因为它会自动处理编译、打包、安装和启动。
手动执行
assembleDebug
(或assemble
相关任务) 然后再执行installDebug
。 这种方式在你需要更精细控制构建过程时有用。
本质上,appDebug
并不是一个独立的、能“使变化生效”的魔法任务。它是 Android 构建系统和 IDE 背后复杂流程的一部分,而这些流程的核心是确保你的最新代码被正确地编译和打包成可执行的 APK。installDebug
只是这个流程的最后一步,负责部署已经准备好的应用程序。
5.Attach Debugger to Android Process和Sync Project with Gradle Files的作用
Attach Debugger to Android Process 的作用
简单来说,这个功能允许你在不重新启动应用的情况下,将调试器连接到已经运行在设备或模拟器上的应用进程。
想象一下以下场景:
- 你的应用正在后台运行,或者你正在通过其他方式(比如从主屏幕点击图标)启动它,而不是直接从 Android Studio 运行。
- 你发现了一个 bug,想要在应用运行状态下实时检查变量的值、查看调用堆栈,或者设置断点。
在这种情况下,你不需要重新编译和运行整个应用,只需点击 Attach Debugger to Android Process 按钮。Android Studio 会弹出一个窗口,列出当前所有可调试的进程。你只需选择你的应用进程,调试器就会立即连接上。这大大节省了开发时间,尤其是在调试那些需要特定启动流程或长时间运行才能复现的 bug 时。它允许你在应用运行的任何时刻开始调试,而不是每次都必须从头开始。
Sync Project with Gradle Files 的作用
这个功能的作用是同步你的项目配置,确保你的代码、资源和依赖项与 build.gradle
文件中的设置保持一致。
Gradle 是 Android 项目的构建系统,它负责编译你的代码、打包你的资源,并处理你的依赖项。你的项目的所有配置信息,比如应用的 SDK 版本、应用的依赖库(如 AppCompat、Glide、Retrofit 等),以及构建类型等,都定义在 build.gradle
文件中。当你对 build.gradle
文件做出任何修改时(例如,添加了一个新的依赖库,或者修改了应用的 targetSdkVersion
),Gradle 需要重新构建项目以应用这些更改。
这就是 Sync Project with Gradle Files 按钮的作用。点击它之后,Android Studio 会执行以下操作:
解析
build.gradle
文件:读取你所有的配置更改。下载新的依赖项:如果你的
build.gradle
文件中新增了依赖库,Gradle 会自动从 Maven 中央仓库或其他仓库下载这些库。生成项目结构:根据新的配置,重新组织和生成项目的内部结构,使得你的代码编辑器(比如自动补全)能够正确识别新的类和方法。
简而言之,每次修改 build.gradle
文件后,你都必须点击“Sync Project with Gradle Files”按钮,否则 Android Studio 将无法识别你的更改,你的项目可能会无法编译。
二、git的保存方式
1.git-stash的使用
git stash
是 Git 中一个非常有用的命令,它允许你临时保存你当前工作目录中那些还没有提交的修改(包括已暂存和未暂存的改动),然后将工作目录恢复到 HEAD 提交时的干净状态。这在你需要切换分支处理紧急问题,但又不想提交不完整的修改时非常方便。
it stash
或git stash push
: 不带任何参数执行git stash
或git stash push
会将所有已修改和已暂存的文件保存起来,并生成一个默认的描述信息。git stash push -m "你的描述信息"
: 强烈推荐使用此命令。-m
选项让你为你的 stash 添加一个有意义的描述信息,这在你有多个 stash 时非常有用,可以帮助你记住每个 stash 的内容。git stash -u
或git stash --include-untracked
: 默认情况下,git stash
不会保存未跟踪的文件(即你刚刚创建但尚未通过git add
添加到 Git 跟踪的文件)。使用这个选项可以包含这些未跟踪文件。git stash -a
或git stash --all
: 这个选项比-u
更强大,它不仅包括未跟踪的文件,还会包括 Git 忽略的文件(由.gitignore
指定的文件)。使用此选项时要小心,因为它可能会保存你不想保存的文件。
git stash list:这个命令用于查看你当前保存的所有 stash 列表。
git stash pop:这个命令用于取出并应用最近(即 stash@{0}
)的 stash,并从 stash 列表中删除该 stash。
2.stash
和 shelf
的区别
git stash
是 Git 版本控制系统的一个内置功能。而 "Shelve" (搁置) 通常是 IDE (集成开发环境),特别是 JetBrains 系列 IDE (如 IntelliJ IDEA, WebStorm, PyCharm 等) 提供的一个独有功能。
Stash: 是 Git 本身的功能。你可以在任何 Git 仓库中使用 git stash
命令,无论你使用什么编辑器或 IDE。在内部:Git 将你的改动打包成一个特殊的 commit 对象存储在 .git
目录下,并维护一个 stash 列表。这些 stash 可以像普通提交一样被 Git 命令行工具操作、查看、应用或删除。git stash
默认会保存你整个工作目录中所有已修改和已暂存的改动(包括未跟踪的文件,如果指定了 -u
或 -a
)。总结主要是Git功能
Shelf: 是 IDE 特定的功能。它由 IDE 管理和实现,通常无法在 IDE 之外使用或查看。IDE 通常会将你的改动保存为补丁文件(patch files)或其他内部格式,存储在 IDE 的配置目录中。这些搁置的改动只能通过 IDE 的界面进行管理和应用。大多数 IDE 的搁置功能允许你更细粒度地选择要搁置的改动,例如只搁置某个文件、某个变更列表 (changelist) 或文件中的某一行改动。这在只处理部分改动时非常方便。
最后的保证:Local History 是许多现代 IDE (如 JetBrains 系列 IDE、VS Code 等) 提供的一个非常强大的本地文件版本管理功能。它独立于任何外部版本控制系统 (如 Git),在你的代码发生变化时自动保存文件的快照。