最近接手了一个棘手的远程技术支持案例:某机械制造团队的Unity应用在定制Android设备上运行时,会不定期出现前台闪退现象。由于设备部署在外地工厂,团队缺乏Android开发经验,且现有的Bugly监控上报信息过于繁杂,导致问题排查陷入僵局。
这种场景在工业物联网应用中很常见——嵌入式设备运行定制化应用,出现问题后难以现场调试。传统解决方案存在三个痛点:
基于adb logcat命令构建自动化监控工具,主要考虑以下技术路径:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 代码埋点 | 精准捕获业务逻辑 | 需重新打包发布 | 长期稳定项目 |
| 第三方SDK | 功能完善 | 数据延迟/冗余 | 成熟产品 |
| adb脚本 | 无需改代码 实时性强 |
需USB连接 | 紧急问题排查 |
最终选择adb方案的核心考量:
plaintext复制 +---------------------+
| Main Script |
+----------+----------+
|
+--------------------+--------------------+
| | |
+-------+-------+ +-------+-------+ +-------+-------+
| 实时错误监控 | | 日志文件记录 | | ANR日志导出 |
+---------------+ +---------------+ +---------------+
| | |
+-------+-------+ +-------+-------+ +-------+-------+
| 设备信息查询 | | 进程级监控 | | 系统日志导出 |
+---------------+ +---------------+ +---------------+
bash复制adb logcat -v time -s ActivityManager:W System.err:E AndroidRuntime:E *:F
参数解析:
-v time:添加时间戳-s:过滤指定tag为避免单个文件过大,采用时间分割方案:
batch复制:: 每30分钟生成新文件
set LOG_FILE=log_%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%.txt
adb logcat -v time > "%LOG_FILE%"
通过adb devices获取设备序列号,支持指定设备抓包:
batch复制for /f "skip=1 tokens=1" %%i in ('adb devices') do (
if not "%%i"=="adb" (
adb -s %%i logcat ...
)
)
Android系统将ANR日志存储在/data/anr/,但需要root权限。采用静默模式避免报错干扰:
batch复制adb pull /data/anr/ "%OUTPUT_DIR%\" 2>nul
if exist "%OUTPUT_DIR%\traces.txt" (
echo ANR日志导出成功
) else (
echo 需要root权限才能导出ANR日志
)
batch复制@echo off
setlocal enabledelayedexpansion
:MAIN_MENU
cls
echo Android日志监控工具 v1.2
echo --------------------------
echo 1. 实时显示错误日志
echo 2. 记录日志到文件
echo 3. 导出ANR日志
echo 4. 查看设备信息
echo 5. 退出
set /p choice=请选择操作:
if "%choice%"=="1" call :REALTIME_MONITOR
if "%choice%"=="2" call :LOG_TO_FILE
if "%choice%"=="3" call :EXPORT_ANR
if "%choice%"=="4" call :DEVICE_INFO
if "%choice%"=="5" exit /b
goto MAIN_MENU
batch复制:MONITOR_PROCESS
set /p package=输入应用包名:
for /f "tokens=2" %%i in ('adb shell "ps | grep %package%"') do set pid=%%i
if "%pid%"=="" (
echo 未找到运行中的进程
) else (
adb logcat -v time --pid=%pid%
)
pause
goto MAIN_MENU
batch复制:EXPORT_SYSTEM_LOGS
set EXPORT_DIR=logs_%date:~0,4%%date:~5,2%%date:~8,2%
mkdir "%EXPORT_DIR%"
adb logcat -d > "%EXPORT_DIR%\full.log"
adb logcat -d -b events > "%EXPORT_DIR%\events.log"
adb shell dumpsys meminfo > "%EXPORT_DIR%\meminfo.txt"
echo 系统日志已导出到 %EXPORT_DIR% 目录
pause
goto MAIN_MENU
遇到Native层崩溃时,重点关注以下日志特征:
code复制signal 11 (SIGSEGV), code 1 (SEGV_MAPERR) // 内存访问违规
backtrace: // 调用栈
#00 pc 002acaf0 /data/app/.../libunity.so // 崩溃so库
Build fingerprint: 'qti/msm8953_64...' // 设备指纹
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 设备未识别 | USB调试未开启 驱动未安装 |
执行adb devices验证检查设备授权弹窗 |
| 日志乱码 | 系统编码不匹配 | 添加CHCP 65001切换UTF-8 |
| ANR导出失败 | 权限不足 | 使用adb root获取权限或联系设备厂商 |
| 日志延迟 | 缓冲区限制 | 调整缓冲区大小:adb logcat -G 4M |
过滤策略优化:
bash复制# 只监控目标应用日志
adb logcat --pid=$(adb shell pidof com.example.app)
# 过滤NDK日志
adb logcat | grep -E 'libc|signal|DEBUG'
网络传输优化:
bash复制# 使用WiFi调试(需先USB授权)
adb tcpip 5555
adb connect 设备IP:5555
创建完整工具包应包含:
code复制├── adb_tool/
│ ├── adb.exe # 平台适配版本
│ ├── AdbWinApi.dll
│ ├── log_monitor.bat # 主脚本
│ └── README.txt # 图文操作指南
└── driver/ # 特殊设备驱动
设备连接检查清单:
adb devices确认设备ID出现典型使用流程:
mermaid复制graph TD
A[双击log_monitor.bat] --> B{选择功能}
B -->|实时监控| C[查看控制台输出]
B -->|日志记录| D[查看生成的log_*.txt]
B -->|ANR分析| E[检查traces.txt]
结合Windows任务计划程序,实现无人值守监控:
创建基本监控脚本:
batch复制@echo off
set LOG_DIR=C:\AndroidLogs
mkdir "%LOG_DIR%" 2>nul
adb logcat -v time > "%LOG_DIR%\%date%.log"
设置每天定时执行:
powershell复制$Trigger = New-ScheduledTaskTrigger -Daily -At 9am
Register-ScheduledTask -TaskName "AndroidLog" -Trigger $Trigger -Action (New-ScheduledTaskAction -Execute "C:\adb_tool\monitor.bat")
使用Python实现日志自动分析:
python复制import re
def analyze_crash(log_path):
with open(log_path) as f:
log = f.read()
if 'SIGSEGV' in log:
print('发现Native崩溃')
# 提取崩溃堆栈
stack = re.search(r'backtrace:(.*?)(?=\n\n)', log, re.DOTALL)
if stack:
print(stack.group(1))
编码问题:
CHCP 65001解决中文乱码设备兼容性:
batch复制:: 检测设备API级别
adb shell getprop ro.build.version.sdk
:: API<24需要调整时间格式
长期监控注意事项:
这个方案在三个不同项目中成功应用后,我总结出最关键的经验是:对于工业场景的Android问题排查,轻量级和可操作性往往比功能全面更重要。把80%的精力放在20%的核心功能上(错误捕获+基础信息收集),才能让非技术团队真正用起来。