在日常的 Android 项目开发中,我们通常会使用 adb 命令来获取连接设备的内存、屏幕、CPU等信息,也会使用 gradle 命令来获取项目构建相关的 projects、tasks、dependencies等信息,还会使用 git 命令来获取代码 commit、log、diff 等信息。这些信息的获取,每次都在command 中输入相关命令进行操作(有时命令记不住,还需要查询一下),重复的操作让人感到厌倦和疲乏。现在,可以尝试使用 python 来简化这一部分工作,将常用的执行命令封装到 python 脚本中,每次想要获取某个信息时,就直接执行相关 python 脚本。这样就可以省去开发中的细碎工作。(将脚本一次写好,使用到退休:))
另外,git脚本 适用与任何项目,包括Python, Android, iOS项目等。
Python Version 3.9.6
执行 gradle/native_libs.py
需要安装库 numpy
在日常的 Android 项目开发中,通常使用 adb 命令来获取屏幕、设备、应用程序等信息。
在 adb 目录下,是用 Python 封装的常用 adb 命令脚本:
adb.py
:adb 命令脚本汇总getprop.py
:获取设备的属性信息mainactivity.py
:获取设备三方应用程序的 main activitypm.py
:获取设备上的三方应用程序包名proc.py
: 获取关于系统和进程的信息screenshot.py
:获取截屏文件,并在电脑上打开topactivity.py
:获取设备当前应用程序当前activitywm.py
: 获取设备屏幕信息
获取设备的属性信息:
python3 getprop.py
输出结果:
//.....省略
[dalvik.vm.dexopt.secondary]: [true]
[dalvik.vm.heapgrowthlimit]: [384m]
[dalvik.vm.heapmaxfree]: [8m]
[dalvik.vm.heapminfree]: [2m]
[dalvik.vm.heapsize]: [512m]
[dalvik.vm.heapstartsize]: [8m]
[dalvik.vm.heaptargetutilization]: [0.75]
//.....省略
[ro.system.build.version.release]: [10]
[ro.system.build.version.sdk]: [29]
//.....省略
[ro.product.vendor.device]: [kirin980]
[ro.product.vendor.manufacturer]: [HUAWEI]
[ro.product.vendor.model]: [kirin980]
[ro.product.vendor.name]: [kirin980]
//.....省略
获取设备三方应用程序的 main activity:
python3 mainactivity.py
输出结果:
Package: com.dianping.v1, Main Activity: com.dianping.v1/.NovaMainActivity
Package: com.tencent.mm, Main Activity: com.tencent.mm/.ui.LauncherUI
Package: com.baidu.searchbox, Main Activity: com.baidu.searchbox/.SplashActivity
Package: com.ss.android.article.news, Main Activity: com.ss.android.article.news/.activity.SplashActivity
Package: com.UCMobile, Main Activity: com.UCMobile/.main.UCMobile
//.....省略
获取设备上的三方应用程序包名:
python3 pm.py
输出结果:
package:com.dianping.v1
package:com.tencent.mm
package:com.baidu.searchbox
package:com.ss.android.article.news
package:com.UCMobile
package:com.huawei.browser.fa
package:com.ss.android.ugc.aweme
package:com.tencent.mobileqq
package:com.netease.newsreader.activity
package:com.suning.mobile.ebuy
//.....省略
获取关于系统和进程的信息:
python3 proc.py
输出结果:
系统的版本信息:
Linux version 4.14.116 (HarmonyOS@localhost) (Android (5484270 based on r353983c) clang version 9.0.3 (https://android.googlesource.com/toolchain/clang 745b335211bb9eadfa6aa6301f84715cee4b37c5) (https://android.googlesource.com/toolchain/llvm 60cf23e54e46c807513f7a36d0a7b777920b5881) (based on LLVM 9.0.3svn)) #1 SMP PREEMPT Wed Apr 19 17:33:59 CST 2023
--------------------------------------------------
CPU 信息:
Processor : AArch64 Processor rev 0 (aarch64)
processor : 0
BogoMIPS : 3.84
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp
CPU implementer : 0x41
CPU architecture: 8
CPU variant : 0x1
CPU part : 0xd05
CPU revision : 0
//.....省略
--------------------------------------------------
内存信息:
MemTotal: 5765848 kB
MemFree: 326496 kB
MemAvailable: 775392 kB
Buffers: 1720 kB
Cached: 740196 kB
//.....省略
--------------------------------------------------
当前运行的进程信息:
Name: cat
Umask: 0000
State: R (running)
Tgid: 13681
Ngid: 0
Pid: 13681
PPid: 8617
//.....省略
--------------------------------------------------
文件系统信息:
37 24 253:7 / / ro,relatime shared:1 - erofs /dev/block/dm-7 ro,seclabel,user_xattr,lz4asm
38 37 0:18 / /dev rw,nosuid,relatime shared:2 - tmpfs tmpfs rw,seclabel,size=2850668k,nr_inodes=712667,mode=755
//.....省略
如果需要单独获取某一项信息,可以使用:
- 系统的版本信息:
python3 proc.py version
- CPU 信息:
python3 proc.py cpuinfo
- 内存信息:
python3 proc.py meminfo
- 当前运行的进程信息:
python3 proc.py status
- 文件系统信息:
python3 proc.py mountinfo
获取截屏文件,并在电脑上打开:
python3 screenshot.py
输出结果:
From: /sdcard/Pictures/Screenshots/Screenshot_20240129_120423.png, To: /Users/wangjiang/Desktop/Screenshot_20240129_120423.png
这个就不展示具体操作结果了。
获取设备当前应用程序当前activity:
python3 topactivity.py
输出结果:
ACTIVITY com.petal.litegames/com.huawei.litegames.LiteGamesActivity 5e73dc2 pid=16955
获取设备屏幕信息:
python3 wm.py
输出结果:
Physical size: 1080x2244
Physical density: 480
使用 python3 adb.py
是上面脚本的汇总,可以在命令行执行:
- 获取设备的属性信息:
python3 adb.py getprop
- 获取设备三方应用程序的 main activity:
python3 adb.py mainactivity
- 获取设备上的三方应用程序包名:
python3 adb.py pm
- 获取关于系统和进程的信息:
python3 adb.py proc
- 获取截屏文件,并在电脑上打开:
python3 adb.py screenshot
- 获取设备当前应用程序当前activity:
python3 adb.py topactivity
- 获取设备屏幕信息:
python3 adb.py wm
在日常的 Android 项目开发中,通常使用 gradle 命令来获取项目 tasks、projects、dependencies等信息,或执行自定义的 task。
在 gradle 目录下,是用 Python 封装的 gradle 命令脚本:
- dependencies.py:将项目依赖信息保存到文件,并在浏览器中打开
- dependencyinsight.py:将项目中特定依赖项的详细信息保存到文件,并在浏览器中打开
- native_libs.py:与 native_libs.gradle 对应,将项目 so 依赖信息保存到 html 文件,并在浏览器中打开
使用 python3 dependencies.py android_project_path
,android_project_path 为项目路径:
python3 dependencies.py /Users/wangjiang/Public/software/android-workplace/Demo
输出结果:
Report File Path: /Users/wangjiang/Public/software/android-workplace/Demo/build/reports/app-dependencies.txt
使用 python3 dependencyinsight.py android_project_path dependency
,android_project_path 为项目路径,dependency
为需要查找的依赖库,比如 io.reactivex.rxjava3:rxjava:
python3 dependencyinsight.py /Users/wangjiang/Public/software/android-workplace/Demo io.reactivex.rxjava3:rxjava
输出结果:
Report File Path: /Users/wangjiang/Public/software/android-workplace/Demo/build/reports/app-dependencyInsight.txt
> Task :app:dependencyInsight
io.reactivex.rxjava3:rxjava:3.0.4
variant "runtime" [
org.gradle.status = release (not requested)
org.gradle.usage = java-runtime
org.gradle.libraryelements = jar (not requested)
org.gradle.category = library (not requested)
Requested attributes not found in the selected variant:
com.android.build.api.attributes.BuildTypeAttr = release
com.android.build.api.attributes.ProductFlavor:type = apink
org.gradle.jvm.environment = android
com.android.build.api.attributes.AgpVersionAttr = 7.2.2
org.jetbrains.kotlin.platform.type = androidJvm
]
Selection reasons:
- By conflict resolution : between versions 3.0.4, 3.0.0 and 3.0.2
io.reactivex.rxjava3:rxjava:3.0.4
+--- releaseRuntimeClasspath
//......省略
将本项目、子项目、三方库依赖的 so 信息输出得到 html 文件,快速找到某个 so 信息。甚至可以在 CI/CD 添加该 python 脚本,方便每个开发人员下载查看。
- 把文件
native_libs.gradle
放到 app 的build.gradle
文件所在同级目录下,并在项目build.gradle
中添加依赖:apply from: "./native_libs.gradle"
- 执行
native_libs.py
需要安装库numpy
注意:在 native_libs.gradle
中定义了 so
依赖信息的输出路径:project.buildDir.path + "/reports/so" + "/native_libs.json"
,确保 native_libs.py
中能读到正确的
json 路径。另外,单独在命令行执行 ./gradlew :app:mergeDebugNativeLibs
任务,此时也会输出 so 信息到 native_libs.json 文件中。
使用 python3 native_libs.py android_project_path
,android_project_path 为项目路径:
python3 native_libs.py /Users/wangjiang/Public/software/android-workplace/Demo
输出结果:
Report File Path: /Users/wangjiang/Public/software/android-workplace/Demo/build/report/so/native_libs.html
在项目 CI/CD build 阶段完成后,在 analyze 阶段新增一个 job: so dependency 用于分析项目依赖的 so 信息,例如:
so dependency:
tags:
- apk
- android
stage: analyze
script:
- ./gradlew :app:mergeDebugNativeLibs
after_script:
- python3.9 native_lib.py
artifacts:
name: "$CI_JOB_STAGE}_reports_${CI_PROJECT_NAME}_$CI_COMMIT_REF_SLUG"
when: on_success
expire_in: 3 days
paths:
- "*/build/reports"
only:
- branches
except:
- master
在项目每次跑完 pipeline 后,就会生成一个项目 so 依赖信息报告:native_lib.html ,方便每个开发人员下载查看。
在日常的 Android 项目开发中,一般只会使用到: git add, git commit, git push, git pull, git rebase, git merge, git diff
等常规命令。但是使用 git 命令,还可以做一些特别的事情,比如查看某个版本某个作者的所有提交更改,方便自己或其他人进行
code
review;比如查看某个提交第一次出现的版本,方便排查问题。
在 git 目录下,是用 Python 封装的 git 命令脚本:
- diff_branch.py:查看某个版本某个作者的所有提交更改
- find_commit.py:某个提交第一次出现的 release 版本
- find_duplicated_code.py:使用 pmd cpd 查找项目重复代码
- increment_detect.py:使用 detekt 和 pmd 做增量代码检查
在某个版本迭代中,不管是单人还是多人开发,如果想在 mr 之前 或 之后,或者 release 之前 或 之后,随时查看自己本次版本迭代中的所有提交更改(随时对自己编写的代码进行自我 code review),现只能使用 git 命令:git log branch1...branch2 --author=wangjiang --name-status --oneline 等进行简单查看,而且较麻烦。我们期望有一个工具,能够展示自己当前分支提交的所有代码更改内容。
使用 python3 diff_branch.py project_path current_branch target_branch
,project_path
为项目路径,current_branch 为当前分支,target_branch 为目标分支。适用业务场景:
- current_branch 为 feature 分支,target_branch 为拉出 current_branch 的主分支,比如:current_branch 为
feature/7.63.0-wangjiang,target_branch 为 master 或 release/7.62.0,那么此时
diff_branch.py
用于查看自己在 feature/7.63.0-wangjiang 的提交,也就是该 feature 的提交更改 - current_branch 为 release/7,63.0 分支,target_branch 为 7.62.0 分支,此时
diff_branch.py
用于查看自己在 release/7.63.0 分支上的提交,也就是自己在 7.63.0 版本的所有提交更改
示例:在当前 android-script 项目中,查看自己在 feature 分支 feature/0.0.2-wangjiang 上提交的所有更改(current_branch 为feature/0.0.2-wangjiang,target_branch为release/0.0.1)
python3 diff_branch.py /Users/wangjiang/Public/software/python-workplace/android-script feature/0.0.2-wangjiang release/0.0.1
输出结果:
Html Report Path: /Users/wangjiang/Public/software/python-workplace/android-script/build/reports/diff/WJRye/feature_0.0.2-wangjiang-diff-release_0.0.1.html
毫无疑问:该diff_branch.py
脚本适用与任何项目,包括 Android 项目。
在日常的 Android 项目开发中,如果想排查问题,或查看 feature 在哪个版本上线的,那么查看某个 commit 第一次出现的 release 分支,能够辅助你得到更多有用的信息。
示例:在当前 android-script 项目中,查看 commit id : dd1eee4 第一次出现的 release 分支
python3 find_commit.py /Users/wangjiang/Public/software/python-workplace/android-script dd1eee4
输出结果:
Html Report Path: /Users/wangjiang/Public/software/python-workplace/android-script/build/reports/diff/commit_id/dd1eee4.html
毫无疑问:该find_commit.py
脚本适用与任何项目,包括 Android 项目。
随着项目的不断迭代,以及代码的增加和开发人员的增加,代码规范或代码质量的把控,是当前版本发布前必要的一环。在当前开发流程中:编码→构建→测试→发布,代码规范或代码质量相关问题,只能靠人工 Review,或灰度和线上 Bugly 反馈。人工 Review 代码,可能比较费时以及遗漏部分Case,而灰度和线上 Bugly 反馈,为时已晚。所以,要在版本发布前尽量去发现代码质量问题,避免带到线上(被动反馈),可以在构建过程之前中去添加静态代码检查环节,让每一次的构建都能自动地去分析代码是否存在质量问题。
在日常的 Android 项目开发中,如果每个 release 版本都去做全量静态代码检查,是不切实际的。因为很多项目都存在历史遗留问题,全量静态代码检查,会增加开发人员的工作负担,所以增量静态代码检查才可能实行。
使用上面脚本 diff_branch.py
可以查看某个版本某个作者的所有提交更改
,提交文件包含修改,删除、添加、重命名文件等。那么再结合 detekt 对 kotlin 语言静态代码检查,以及 pmd 对 java
语言静态代码检查,就可以做增量代码检查。
使用命令行运行 pmd 官方文档介绍:pmd doc。首先,在 pmd 的
github releases 中下载目前最新的版本:30-September-2023 - 7.0.0-rc4 中的
pmd-dist-7.0.0-rc4-bin.zip 。下载后解压到resources/cli/pmd中:
使用命令行运行 detekt 官方文档介绍:detekt doc。首先,在 detekt 的
github releases
中下载目前最新的版本:1.23.4 - 2023-11-26 中的
detekt-cli-1.23.4-all.jar。下载后解压到resources/cli/detekt中:
另外,pmd 检查规则配置文件:rulesets.xml,detekt 检查规则配置文件:detekt.yml,这两个文件是根据官方文档写的简易配置。
使用 python3 increment_detect.py project_path current_branch target_branch
,project_path
为项目或代码路径,current_branch 为当前分支,target_branch 为目标分支。执行该脚本后,会输出在 current_branch 分支上提交的代码更改的
java 或 kotlin 静态代码检查结果:
python3 increment_detect.py /Users/wangjiang/Public/software/android-workplace/Demo/src release/7.63.0 release/7.62.0
输出结果:
Report File Path: /Users/wangjiang/Public/software/android-workplace/Demo/build/reports/detekt.html
Report File Path: /Users/wangjiang/Public/software/android-workplace/Demo/build/reports/pmd-java.html
随着项目的迭代,如果没有严格的 Code View,粘贴复制的代码会越来越多。 pmd cpd 可以找到项目中的重复代码,它支持 Java, JSP, C/C++, C#, Go, Kotlin, Ruby, Swift等语言的重复代码检查。
使用 python3 find_duplicated_code.py project_src_path current_branch(可选)
,project_src_path
为项目代码路径,current_branch 为当前分支(也可以不指定)。执行该脚本后,会输出在项目 project_src_path 路径的所有重复代码检查结果:
示例:在当前 android-script 项目中,查看重复代码:
python3 find_duplicated_code.py /Users/wangjiang/Public/software/pycharm/workplace/github/android-script main
输出结果:
Report File Path: /Users/wangjiang/Public/software/pycharm/workplace/github/android-script/build/reports/pmd-cpd-python.html