1. 项目概述从“点按”到“指令”的进阶之路在Android开发与测试的日常里我们习惯了在屏幕上用手指点按来启动一个应用或者从最近任务列表里划掉它来关闭。但当我们需要批量测试、自动化操作或者设备屏幕根本无法直接触控时这种图形交互方式就显得力不从心了。这时adbAndroid Debug Bridge就成了我们连接电脑与设备、用命令行精准操控应用的“瑞士军刀”。今天要聊的就是其中最基础也最核心的三个操作关闭、启动和重启App。这听起来简单不就是几个命令吗但真正用起来你会发现里面门道不少怎么确保关得干净怎么指定启动某个特定界面重启时数据会不会丢这些都是在实际自动化测试、爬虫控制或者日常调试中必须面对的问题。无论你是刚接触Android测试的新手还是需要编写稳定自动化脚本的老手吃透这几个命令都能让你的效率提升一个档次。2. 核心原理与工具准备2.1 ADB工具的本质与工作原理adb本身是一个包含三部分的客户端-服务器程序客户端运行在你开发机上的adb命令就是你即将在终端Windows的CMD/PowerShellMac/Linux的Terminal里输入的东西。守护进程adbd运行在Android设备或模拟器后台的一个服务负责接收和执行来自客户端的命令。服务器同样运行在开发机上作为一个后台进程管理客户端与守护进程之间的通信。当你输入adb shell am start ...时命令的旅程是这样的客户端将指令发送给开发机上的adb服务器服务器通过USB或网络找到已连接的设备并与设备上的adbd守护进程建立连接最终由adbd在设备系统层面执行相应的ActivityManager命令。理解这一点很重要因为它解释了为什么必须先确保设备通过adb devices命令被正确识别后续的amActivity Manager命令才能生效。2.2 环境配置与连接校验工欲善其事必先利其器。在敲下任何命令之前稳定的环境是前提。1. 获取ADB工具包通常有两种方式通过Android SDK如果你安装了Android StudioADB工具位于[SDK安装目录]/platform-tools/下。这是最推荐的方式因为它能保证版本兼容性。独立下载可以从Android开发者官网单独下载platform-tools包解压即用。2. 配置系统环境变量将上述platform-tools目录的完整路径添加到系统的PATH环境变量中。这样你才能在任意终端窗口直接输入adb命令。3. 连接设备与授权真机连接用USB线连接手机和电脑。在手机上弹出的“允许USB调试吗”对话框中务必勾选“始终允许”然后点击确定。这是很多新手卡住的第一步。模拟器连接大多数模拟器如Android Studio自带的AVD、雷电模拟器会自动连接到ADB无需额外配置。验证连接打开终端输入adb devices。如果一切正常你会看到类似以下的输出List of devices attached emulator-5554 devicedevice状态表示连接成功且已授权。如果显示unauthorized请检查手机上的授权对话框如果什么都没显示检查USB线、驱动或连接模式需开启“开发者选项”中的“USB调试”。注意有些厂商定制系统如小米、华为在开启USB调试后还需要进入“开发者选项”中额外开启“USB调试安全设置”或“允许通过USB调试修改权限”否则adb shell可能权限不足。3. 核心命令深度解析与实操接下来我们进入正题拆解每一个命令的细节、参数和实战场景。3.1 关闭停止Appam force-stop与am kill关闭App更准确的说法是“停止应用进程”。这里有两个常用命令目的相似但机制略有不同。命令语法adb shell am force-stop package_name adb shell am kill [--user USER_ID] package_namepackage_name这是目标应用的包名是唯一标识符而不是你在桌面上看到的应用名称。获取包名的方法有很多例如adb shell pm list packages列出所有包名。adb shell pm list packages | grep -i weixin过滤出包含“weixin”的应用如微信。在应用商店的网页版URL中或者使用一些桌面工具查看。am force-stop详解这是最常用、最彻底的关闭命令。它会强制停止目标应用及其所有关联的进程、服务、广播接收器等并将其从最近任务列表中移除。相当于你在系统设置里找到应用点击“强制停止”按钮。实操示例关闭微信。adb shell am force-stop com.tencent.mm执行后微信将完全退出后台推送也会暂时停止直到你再次手动打开应用。am kill详解这个命令用于杀死指定应用的后台进程但行为上比force-stop稍微“温和”一些。它主要根据进程的优先级来杀死进程对于拥有前台服务或正在执行重要任务的应用可能无法立即杀死。在大多数自动化测试场景中force-stop是更可靠的选择。实操示例杀死用户10下的微博进程。adb shell am kill --user 10 com.sina.weibo--user参数在多用户设备如平板的工作资料上特别有用用于指定操作哪个用户空间下的应用。选择与注意事项首选force-stop在自动化测试中为了确保每次测试都在干净的初始状态开始务必使用am force-stop来清理上一个测试案例残留的应用状态。数据影响force-stop不会清除应用数据如SharedPreferences、数据库但会终止所有未保存的临时操作。对于需要登录态的应用强制停止后通常需要重新登录。权限要求这两个命令通常需要adb shell具有足够的权限通常是shell用户权限对于已获得调试授权的连接这通常不是问题。但在某些深度定制的ROM上对系统核心应用的强制停止可能会被限制。3.2 启动Appam start的艺术启动一个应用远比想象中复杂因为你要决定是启动主界面还是某个深层页面是否要传递数据是否要清空已有的任务栈基础命令语法adb shell am start [options] INTENTINTENT意图是Android中组件通信的核心在这里用于描述要启动哪个应用的哪个页面Activity。3.2.1 最常用的启动方式1. 启动应用默认入口Launcher Activity这是最常见的场景等同于点击桌面图标。adb shell am start -n package_name/full_activity_name-n参数用于指定明确的组件名。full_activity_name是Activity的完整类名。对于主界面它通常是包名加上主Activity名。如何获取查看应用AndroidManifest.xml中声明为LAUNCHER的Activity。更简单的方法先启动一次应用然后执行adb shell dumpsys activity top | grep ACTIVITY可以查看当前顶层Activity的信息。实操示例启动Chrome浏览器的主页。adb shell am start -n com.android.chrome/com.google.android.apps.chrome.Main2. 通过隐式Intent启动当你不知道具体的Activity名或者想通过某种动作如打开网页、查看图片来启动时使用。adb shell am start -a android.intent.action.VIEW -d data_uri-a指定动作Action。-d指定数据Data。实操示例用默认浏览器打开百度。adb shell am start -a android.intent.action.VIEW -d https://www.baidu.com3.2.2 高级启动参数与场景-WWait等待启动完成。在自动化脚本中非常有用可以确保应用完全启动、界面绘制完成后再执行下一步操作。命令会阻塞直到启动超时或完成并打印耗时。adb shell am start -W -n com.example.app/.MainActivity-SStop在启动目标Activity之前先强制停止force-stop该应用。这保证了每次启动都是一个全新的、干净的应用实例避免了旧状态干扰。这是自动化测试的黄金搭档。adb shell am start -S -n com.example.app/.MainActivity--es传递额外数据可以向启动的Activity传递字符串类型的数据。adb shell am start -n com.example.app/.DetailActivity --es key_user_id 12345在DetailActivity中可以通过getIntent().getStringExtra(key_user_id)来获取值“12345”。-f添加标志位控制Activity的启动模式例如-f 0x10200000常用于结合-S使用确保在新的任务栈中启动。一个综合性的复杂启动示例假设我们要测试一个电商App的商品详情页需要先清空App状态然后直接打开商品ID为“10086”的页面并等待页面加载完成。adb shell am start -S -W -n com.example.shop/.ProductDetailActivity --es product_id 10086这条命令做到了1. 强制停止应用2. 启动指定Activity3. 传递商品ID参数4. 等待启动完成。3.3 重启App组合拳与系统命令Android本身没有直接的“重启App”命令。这里的重启通常指的是模拟一次完整的应用生命周期停止 - 可选等待- 启动。根据测试精度的要求有不同的实现方式。3.3.1 基础重启组合最简单直接的方式就是顺序执行force-stop和start。adb shell am force-stop com.example.app adb shell am start -n com.example.app/.MainActivity这种方式适用于大多数功能测试场景。但需要注意停止和启动是两条独立的命令执行是瞬间的中间没有间隔。如果应用在停止时需要一些时间来处理收尾工作虽然不常见可能会遇到问题。3.3.2 带延迟的精确重启在一些对状态要求严格的场景例如测试应用从完全被杀掉到冷启动的流程我们可以在停止后加入一个短暂的延迟。adb shell am force-stop com.example.app sleep 2 # 在Linux/macOS的shell中等待2秒 adb shell am start -S -n com.example.app/.MainActivity在Windows的批处理或PowerShell中可以使用timeout /t 2来实现等待。3.3.3 使用am restart实际上am命令中确实存在一个restart子命令但它主要用于重启整个系统用户界面或系统服务而非单个应用。adb shell am restart这个命令会重启system_server进程导致系统UI桌面、状态栏重启所有应用都会被杀死然后重新启动其持久化的组件如服务。绝对不要将其用于单个App的重启测试它的影响范围是整个系统。3.3.4 模拟“强杀后恢复”场景这是一种更彻底的重启模拟不仅停止应用还清除其在内存中的所有痕迹然后启动。这可以通过am kill结合ps命令来实现但更粗暴有效的方式是使用adb shell pkill如果设备支持或adb shell kill特定进程ID。不过对于自动化测试force-stop已经足够模拟应用进程被系统回收的场景。重启策略选择建议测试场景推荐命令组合目的与说明常规功能回归测试force-stopstart快速满足大部分用例冷启动性能测试force-stopsleep 2start -W -S确保进程完全死亡并测量冷启动时间应用状态恢复测试不停止应用使用start带上FLAG_ACTIVITY_CLEAR_TOP等标志测试应用内Activity栈的重建逻辑错误示例am restart错误会导致系统UI重启4. 实战脚本编写与自动化集成知道了单个命令如何将它们串联起来形成可重复、可靠的自动化流程这里以两个常见场景为例。4.1 场景一简单的自动化测试清理与启动脚本假设我们每天要对一个App进行冒烟测试测试前需要确保App处于初始状态。#!/bin/bash # 文件名smoke_test.sh APP_PACKAGEcom.example.myapp LAUNCHER_ACTIVITYcom.example.myapp.ui.SplashActivity echo “步骤1: 强制停止应用清理环境...” adb shell am force-stop $APP_PACKAGE # 可选清除应用数据警告这会删除所有用户数据 # adb shell pm clear $APP_PACKAGE # echo “已清除应用数据。” # sleep 3 echo “步骤2: 以干净状态启动应用主界面...” adb shell am start -S -n $APP_PACKAGE/$LAUNCHER_ACTIVITY -W # 判断启动是否成功简单通过-W的输出来判断实际可解析其输出 if [ $? -eq 0 ]; then echo “应用启动成功等待5秒后开始执行测试用例...” sleep 5 # 这里可以插入后续的测试步骤例如用adb shell input模拟点击 # adb shell input tap 500 1000 # 点击屏幕某位置 else echo “应用启动失败请检查” exit 1 fi echo “冒烟测试前置条件准备完毕。”4.2 场景二循环压力测试反复重启测试App在频繁被杀死和启动下的稳定性如内存泄漏、崩溃率。#!/bin/bash # 文件名stress_restart.sh APP_PACKAGEcom.example.myapp MAIN_ACTIVITYcom.example.myapp.MainActivity CYCLE_COUNT50 for ((i1; iCYCLE_COUNT; i)) do echo “第 $i 轮重启测试开始 ---” echo “停止应用...” adb shell am force-stop $APP_PACKAGE sleep 1 # 给系统一点清理时间 echo “启动应用...” # 使用-W并捕获输出可以分析每次启动耗时 adb shell am start -S -W -n $APP_PACKAGE/$MAIN_ACTIVITY start_log_$i.txt 21 # 检查启动后是否有“崩溃”或“无响应”的对话框出现简单示例 adb shell dumpsys window windows | grep -E “Application Error|Application Not Responding” if [ $? -eq 0 ]; then echo “警告在第 $i 轮可能检测到应用异常” stress_test_report.log fi echo “应用运行中等待10秒...” sleep 10 echo “第 $i 轮重启测试结束 ---” echo “” done echo “压力测试完成共执行 $CYCLE_COUNT 个循环。”这个脚本会记录每次启动的日志并尝试检测明显的ANR应用无响应或崩溃对话框将潜在问题记录到报告文件中。4.3 在PC端批处理或Python中调用在Windows环境下你可以编写一个.bat批处理文件。echo off set PACKAGE_NAMEcom.tencent.mm set ACTIVITY_NAMEcom.tencent.mm.ui.LauncherUI echo 正在关闭微信... adb shell am force-stop %PACKAGE_NAME% timeout /t 1 /nobreak nul echo 正在启动微信... adb shell am start -n %PACKAGE_NAME%/%ACTIVITY_NAME%在Python中你可以使用subprocess模块更灵活地调用adb命令并解析其输出。import subprocess import time def restart_app(package, activity): # 停止应用 stop_cmd f“adb shell am force-stop {package}” subprocess.run(stop_cmd, shellTrue, capture_outputTrue) time.sleep(1.5) # 启动应用 start_cmd f“adb shell am start -n {package}/{activity}” result subprocess.run(start_cmd, shellTrue, capture_outputTrue, textTrue) if result.returncode 0: print(f“应用 {package} 重启成功”) # 可以进一步解析result.stdout获取-W的耗时 else: print(f“启动失败: {result.stderr}”) if __name__ “__main__”: restart_app(“com.example.app”, “com.example.app.MainActivity”)5. 常见问题排查与实战技巧在实际操作中你肯定会遇到各种“坑”。这里总结了一些典型问题及其解决方案。5.1 问题排查清单问题现象可能原因排查步骤与解决方案adb devices无设备或显示unauthorized1. USB线或端口故障2. 驱动未安装3. 手机未开启USB调试4. 未点击授权弹窗1. 换线、换端口。2. 安装对应手机厂商的USB驱动。3. 进入“开发者选项”确认“USB调试”已开启。4. 检查手机屏幕是否有授权提示勾选“始终允许”。error: no devices/emulators found设备未连接或adb服务异常1. 执行adb kill-server然后adb start-server重启adb服务。2. 确认模拟器已启动或真机已重新插拔。Activity not started或Error: Not found1. 包名或Activity名错误2. 应用未安装在该用户空间3. Activity未在Manifest中导出(exported“true”)1. 用adb shell pm list packages | grep 关键词确认包名。2. 用adb shell dumpsys package pkg | grep userId查看安装用户启动时加--user id。3. 对于非Launcher Activity需确保其exported“true”或调用者有相应权限。命令执行成功但App界面无变化1. 启动的Activity不是预期界面2. 应用有启动页(Splash)或逻辑判断3. 设备屏幕未点亮或锁屏1. 使用adb shell dumpsys activity top确认当前顶层Activity。2. 检查应用逻辑可能需要先启动主Activity。3. 使用adb shell input keyevent KEYCODE_WAKEUP唤醒屏幕。am force-stop对系统应用无效系统应用受保护1. 尝试adb shell pm disable-user package禁用需root或adb有更高权限。2. 对于测试考虑使用模拟器或已root的设备。启动命令带参数无效Intent参数格式错误或Activity未处理1. 检查--es,--ei等参数格式是否正确键值对是否完整。2. 确认目标Activity的onCreate或onNewIntent方法有处理对应Extra的代码。5.2 必备的辅助调试命令掌握这些命令能让你在调试时如虎添翼查看当前任务栈adb shell dumpsys activity activities | grep -A 20 “Running activities”。这个命令能输出当前所有Activity的栈信息对于理解应用界面层级和调试跳转问题至关重要。查看前台应用包名adb shell dumpsys window windows | grep mCurrentFocus。快速知道当前哪个应用在最前面。监控应用日志adb logcat -s ActivityManager:I | grep -E “(Displayed|Focused)”。可以过滤出Activity启动和获得焦头的系统日志配合-W参数计算启动时间。模拟用户输入adb shell input系列命令如input tap点击、input text输入文字、input keyevent按键是自动化测试的核心。5.3 来自实战的经验之谈包名是王道永远不要凭记忆或猜测来写包名和Activity名。编写脚本时先通过命令或工具准确获取它们。一个字符的错误都会导致命令失败。-S和-W是测试好伙伴在自动化脚本中养成使用-S先停止来保证环境干净使用-W等待完成来同步脚本执行节奏的习惯。这能极大提高测试的稳定性和可重复性。理解“停止”与“清除数据”的区别force-stop不会删除你的登录信息、本地缓存。而pm clear package_name会清空所有应用数据包括数据库、设置、账户信息让应用回到首次安装的状态。在自动化中谨慎使用clear除非你确实需要测试首次启动流程。多设备/多用户处理如果你的电脑连接了多个设备或模拟器需要在每条adb命令前指定设备adb -s device_serial shell ...。对于多用户设备注意--user参数的使用。超时与重试机制在生产级的自动化脚本中不要假设每条命令都能一次成功。对关键命令如启动应用添加超时判断和失败重试逻辑是提升脚本健壮性的关键。日志是你的眼睛当命令行为不符合预期时第一时间打开adb logcat过滤相关标签如ActivityManager你的应用包名查看详细的系统日志和应用日志这是定位问题最直接的方法。