Android Framework 开发调试技巧(十月份更新)
Android系统framework开发(包含kernel、graphics、adb、性能、display等)调试技巧笔记
1. readelf命令查看ELF格式的文件信息
常见的文件比如动态库(*.so
)、静态库(*.a
),常用命令:readelf -a libgui.so | grep test_string
2. 查看手机内存
adb shell
cat proc/meminfo
MemTotal: 7821184 kB
MemFree: 157484 kB
MemAvailable: 2765976 kB
Buffers: 175624 kB
Cached: 2264796 kB
......
3. adb logcat缓存管理
adb root;adb remount
清除缓存 adb logcat -c
如果不能清除,就指定区域清除 adb logcat -c main/system/event/kernel/all(日志缓冲区)
查看缓存 adb logcat -g
设置最大logcat缓存 adb logcat -G 100M
4. linux离线翻译工具sdcv
安装:
sudo apt-get install sdcv
使用:
sdcv
只能翻译单词
5. apt-get命令列出版本号
sudo apt-cache madison openssh-client
6. Linux安装tar.xz软件包
在linux下(node.js):
解压后将bin目录的命令全局,建立软链接:
sudo ln -s /node-v10.16.0-linux-x64/bin/node /usr/local/bin/node
sudo ln -s /node-v10.16.0-linux-x64/bin/npm /usr/local/bin/npm
7. JNI的jlong类型打印
不使用%lld和%ld,而是先将其转换成long,然后%ld打印。
ALOGD("Mylog: JNI destroySurface nativeObject=%ld", (long)nativeObject);
8. monkey测试
8.1. 指令参数
adb shell monkey help查看帮助
-p 指定包名
-v log详细程度(最高支持-v -v -v)
-s 种子(指定后,同一个命令在任意时间地点的执行顺序相同)
--throttle 单步延时(每步操作间隔,单位ms),如果不知定系统会尽快的发送事件序列
--kill-process-offer-error 出错是杀掉进程
--ignore-timeouts 忽略超时错误(程序未响应),不会应ANR而停止
--ignore-security-exceptions 忽略证书或认证异常
--hprof 测试前后会生成app内存快照文件(一般在/data/misc目录下生成hprof文件,可以使用Android Studio查看)
--ignore-crashes 忽略crash,不会因crash而停止
--ignore-native-crashes 忽略native代码发生的crash崩溃,不会因此停止
--monitor-native-crashes 监视native代码发生的崩溃
8.2. 示例
(1) adb shell monkey -p PackageName -v -v -v -s 12 –throttle 500 1000 > monkey.txt 随机数种子是12,log详细程度最高,单步延时500ms,总执行1000步,日志输出到monkey.txt
(2) adb shell monkey -p PackageName –throttle 200 –ignore-security-exceptions -v 100000000
(3) adb shell monkey -p PackageName –throttle 200 –ignore-crashes –ignore-timeouts –ignore-security-exceptions –ignore-native-crashes –monitor-native-crashes -v -v -v 1000000 > monkeylog.txt
(4) 不指定包: adb -s DeviceID shell monkey –throttle 200 –ignore-crashes –ignore-timeouts –ignore-security-exceptions –ignore-native-crashes –monitor-native-crashes –ignore-security-exceptions -v -v -v 100 > monkeylog.txt
(5) 正常测试验证问题使用(不忽略crash,压力测试,所以不指定间隔时间): adb -s DeviceID shell monkey -p PackageName –throttle 200 –ignore-security-exceptions -v 100000000 > monkeyLog.txt
8.3. 停止monkey测试
(1) ps -A|grep monkey
(2) kill pid(11111)
8.4. 重现monkey测出的bug
monkey日志搜索ANR exception
,将之前的事件重新操作。尤其是seed值要一样,如monkey -p PackageName -v seed(-s) 100(seed的值) 500(随机时间次数)
9. dump meminfo
adb shell dumpsys meminfo
或者具体包
adb shell dumpsys meminfo packageName
10. kernel使用printk调试
- 打印调试log
printk("%d",intA);
- 打印变量所占内存大小
printk("sizeof(*intA)=%d",sizeof(*intA);
11. 查看设别是否支持Project Teable
Project Treble是在最新的Android上应用兼容的芯片驱动,加快最新系统适配的速度。
adb shell getprop ro.treble.enabled
12. 查看cpu架构
adb shell getprop ro.product.cpu.abi
13. Service服务命令
服务列表: adb shell service list
检测某服务是否存在: adb shell service check SurfaceFlinger
14. 测试CtsMediaTestCases需要CTS媒体文件(连接外网)
Google官网下载,例如CTS媒体文件1.4,解压后阅读README文件,按照提示copy文件到device。
chmod 544 copy_media.sh
./copy_media.sh
chmod 544 copy_images.sh
./copy_images.sh
例如:run cts-dev --module CtsMediaTestCases --compatibility:module-arg CtsMediaTestCases:include-annotation:android.platform.test.annotations.RequiresDevice
15. 当前活动Activiy
15.1. 获取当前ACTIVITY
adb shell dumpsys activity top|grep ACTIVITY
15.2. 命令启动指定Activity
adb shell am start -n ActivityName
16. Android SDK抓取systrace
进入Android/Sdk/platform-tools/systrace目录下
python systrace.py -b 8000 -t 5 -o systrace.html
16.1. 打开模拟Vsync,从Systrace查看到
- 源码: Android 10的AOSP
- 方法: 修改
surfaceflinger/Scheduler/DispSync.cpp
的static const bool kEnableZeroPhaseTracer = false;
为True
17. adb devices很少识别
方法一:
lsusb 查看usb是否识别到手机
如果没有,检查“开发者选项 -> USB调试”是否打开
方法二: 重启ADB服务
adb kill-server
adb start-server
17.1. 添加usb设备自动识别信息/etc/udev/rules.d/
(1)lsusb查看usb链接设备
(2)然后编辑/新增文件(/etc/udev/rules.d/):
sudo vi 51-android.rules 文件内容:
SUBSYSTEM=="usb",ATTRS{idVendor}=="093a",ATTRS{idProduct}=="120d",MODE="0666"
(3)保存后重启udev服务
sudo /etc/init.d/udev restart或者sudo service udev restart
(4)重新连接设备测试
18. adb shell获取设备信息参数(序列号)
getprop 查看机器的全部信息参数
getprop ro.serialno 查看机器的序列号
getprop ro.carrier 查看机器的CID号
getprop ro.hardware 查看机器板子代号
getprop ro.bootloader 查看SPL(Hboot)版本号
getprop ro.build.version.release 查看系统版本(8、9...)
getprop ro.build.display.id 获得厂商系统版本
19. Android中CPU频率查看和修改
root权限(直接输入su命令)
cd sys/devices/system/cpu/cpu0/cpufreq
ls文件如下
cpuinfo_cur_freq: 当前cpu正在运行的工作频率
cpuinfo_max_freq:该文件指定了处理器能够运行的最高工作频率 (单位: 千赫兹)
cpuinfo_min_freq :该文件指定了处理器能够运行的最低工作频率 (单位: 千赫兹)
20. Ubuntu下载更新杀毒软件
下载:
sudo apt-get update
sudo apt-get install clamav
sudo chmod 777 freshclam.lg
freshclamg更新
扫描:
clamav -a /
21. 安装deb包
sudo dpkg -i gapid-1.3.1-linux.deb
22. 查看手机服务
开发者选项 -> Running services可以查看正在运行的服务,以及运行内存情况
23. 查看修改屏幕分辨率和密度
查看:
adb shell
wm size 获得手机当前分辨率
wm density 获得手机当前屏幕密度(例如560dpi)
修改:
wm size 1096*2560
wm density 420
恢复:
wm size reset
wm density reset
24. 查看进程map虚拟地址
adb root;adb remount
adb shell
ps -A|grep camera 查看服务的进程号(例如4712)
cd proc/4712 进入进程号的文件夹
more maps 查看虚拟内存地址
25. SELinux模式开启关闭
SELinux(Security-Enabled Linux)是美国国家安全局(NSA)对于强制访问控制的实现(安全子系统)
临时生效方法:
adb shell setenforce 0(临时生效,关闭SELinux模式)
adb shell setenforce 1(启用,开启SELinux模式)
26. adb命令 – 录制手机视频
adb shell screenrecord sdcard/record.mp4
1adb pull sdcard/record.mp4 .
27. adb命令 – 截图
adb shell screencap -p sdcard/1.png
28. adb命令 – 输入文本
节省手动输入的时间:
adb shell input text ****
29. adb命令 – 获取APP路径
adb shell dumpsys SurfaceFlinger 最下方查看正在运行的APK
adb shell pm path "com.**" 获取路径
30. 台式机通过WIFI建立adb连接,实现无线连接手机
通常在需要手机连接外设显示设备的同时需要抓取Log、Dump等操作:
- 两台手机连上同一个无线网
- 其中一台A关闭开发者选项的USB调试,并且连接到电脑作为热点(无线网卡)
- 另一台B连接电脑输入
adb tcpip 5555
,然后输入adb shell ifconfig wlan0
查看B的IP地址 - 连接B手机的IP: adb connect IP
- 断开B,保持A连接在电脑
31. 连接DP继续dump SurfaceFlinger的方法
- 连接DP前启动:
adb shell dumpsys SurfaceFlinger --file --no-limit
- 断开DP后再次执行结束Dump:
adb shell dumpsys SurfaceFlinger --file --no-limit
- 接过文件pull出来:
adb pull /data/misc/wmtrace/dumpsys.txt
32. md5sum命令检测文件
通过md5sum filename
查看文件的md5sum值
是否一样
33. GSI含义
GSI是替换成google的frameworks等(即system.img, 即google的原生AOSP) system.img包含整个系统,framework、application等,被挂接到”/“目录下,包含系统的所有二进制文件。大概是编译出来的out/target/product/ProductName/system目录的映射
33.1. GSI方法
常用步骤:
adb reboot bootloader (fastboot devices检测设备)
fastboot erase system
fastboot -w
fastboot flash system GSI(.img file)
fastboot reboot
34. CTS VTS跑测注意点
- 重跑:
run retry --retry 序列号
- 跑测arm64-v8a还是armeabi-v7a等:
run cts-suite -s ... -a arm64-v8 -m ...
35. linxu命令查找命令
35.1. 查找字符串
grep -rn 字符串
grep 字符串 -Rin * //查找该目录下包含该字符串的文件
35.2. 查找文件
find . -iname Test*
36. Git命令
- 回退到某个commitID:
git reset --hard commitID
- 新建一个Commit用于Revert某个分支:
git revert commitID
- 修改commit信息
git commit --amend --author="**" --date="**" 修改作者和日期
- 添加topic的方法(提交到Gerrit)
git push origin HEAD:refs/for/BRANCH_Name%topic="name"
- 使用新的change ID覆盖原来已经提交的Patch
git push origin HEAD:refs/changes/99999 (gerrit上的已有Commit的Patch ID)
37. git stash
暂时储藏
用于修改的代码暂时保存起来,并且不影响下次的修改(这个比生成本地补丁方便git format-patch -1 commitID
):
git stash save "Remarks"
执行存储,并且添加备注git stash list
查看储藏列表git stash show stash@{1}
查看某次储藏的修改git stash apply stash@{$Num}
应用某次储藏git stash pop stash@{$Num}
从缓存堆栈中删除某次储藏并且应用到代码中,默认第一个stashgit stash drop stash@{$Num}
从列表删除这个存储git stash clear
删除所有缓存的stash
38. Repo下载项目方法
- 下载
.repo
:repo init -u Git远程仓库 -b Branch_Name(分支选择)
- Sync项目:
repo sync -c -j4
(当前分支) - 如果值Sync指定目录,则在指定目录下执行:
repo sync -c . -j4
39. Android常用编译方式
source build/envsetup.sh
lunch //选择指定Product
make fullbuild -j4
- 如果只编译部分模块:
- framework模块:
make framework -j4
,结果生成framework.jar包到/system/framework - 编译
kernal/msm
使用:make bootimage -j4
- 指定目录下执行:
mm/mmm/mma(依赖编译)
Leave a comment