-
Notifications
You must be signed in to change notification settings - Fork 77
[Discussion] Porting BAAS to Android host platform #400
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
感谢你的pr
ps: 我仅有在安卓开发java app的经验,有关在安卓进行python和c++开发需要先了解一下才能更进一步讨论 |
关于第2点,正在开发中的新ui的前端是基于react的,并且准备完全分离前后端进行开发,打包方面可以考虑react-native或者其他更有利的框架;关于桌面端则考虑tauri和electron择一,个人偏好体积较小的前者,但这一点有待社区讨论。 |
|
确实采用 Web 方案对移动端的兼容性更好,p4a 已有对 Webview 的支持,可以很轻松的打包。至于 React Native,刚才看了一下,理论上可以整合到 p4a 中,不过需要比较多的修改与自定义。如果 React Native 相对 Webview 没有很大的性能优势,我还是偏向于采用简单的 Webview 方案。 对于兼容 u2,u2 的依赖中不兼容的应该只有 adbutils,因此我会先尝试为 adbutils 做一个兼容层,让 adbutils 底层调用 Shizuku 而不是 adb。这样不仅 u2 能正常使用, BAAS 中其他调用 adbutils 的代码也可以正常执行。 另外非常感谢作者能够配合修改 C++ 部分的代码。 |
|
有关ocr图像数据传递, 虽然共享内存无法使用, 但是ocr_server还提供了直接将图片附在http请求file中的方法, 另外我发现安卓直接运行c++编译后的程序十分困难, 最终应该会用ndk把ocr_server编译为so库使用 |
|
多进程应该只有 OCR 部分用到,现在改用 so 库,所以现在不再需要多进程了。 psutil 只有 installer 和模拟器控制部分用到,这两个在 Android 上都不需要,因此 psutil 也不需要了,只要在代码里条件性 import 即可。 |
|
我成功使用ndk编译了onnxruntime 1.22.1 在x86_64 和 arm64-v8a 两个abi下的动态库, armeabi-v7a, x86 无法成功编译, 不知道影响大不大, 后续会测试动态库可用性 |
|
等 C++ 部分准备好了我就开始研究怎么用 Python 调库🤗。 adb 部分,目前已经给 adbutils 的基本功能写了兼容层,足够支持 u2 setup,并且测试可以正常使用 u2。 测试了截图速度,为 ~0.6s,感觉有点慢。 直接访问 RPC 大概在 0.5s 左右。 不过有个地方有点奇怪。如果我使用 baas 的 u2 initer,那么滑动和点击会无法正常使用。没有任何错误,但是也没有效果。 import uiautomator2 as u2
from core.device.uiautomator2_client import BAAS_U2_Initer
d = u2.connect('baas') # 'baas' 是模拟设备的 serial id
init = BAAS_U2_Initer(d._adb_device, logger)
init.install()
print('Swipe')
d.swipe(0.5, 0, 0.5, 0.7, 3)
print('Swipe End')日志: 如果改用 u2 自己的,那么就没有问题。 import uiautomator2 as u2
from core.device.uiautomator2_client import BAAS_U2_Initer
d = u2.connect('baas')
d._force_reset_uiautomator_v2()
print('Swipe')
d.swipe(0.5, 0, 0.5, 0.7, 3)
print('Swipe End')目前还没搞明白是什么原因。不知道是不是调用方式不对? |
|
我已经成功在原始的C++代码上使用NDK编译构建了jni库 相关代码在此分支 |
应该没必要单独一个 apk,这样分发和管理都不太方便。一个 app 内可以同时包含 activity 与 service,把 ocr 做成 service,service 能以独立进程运行,这样一个 app 也可以把主体和 ocr 隔离执行。 service 有两种:
现在算是有三种方案:
1 无论如何都是最简单的。可以考虑用 1 或 2,3 实现起来有点复杂。 如果需要内存共享
|
|
抱歉最近有事没有空关注此pr, 后续会跟进 |


Baas on Android
本 PR 将讨论将 BAAS 移植到手机上,完全脱离电脑运行的可能性,以及我目前验证与移植的进度。
(此 PR 目前仅作讨论,暂不合并)
为什么要移植到 Android 上
根本原因是我想为某个游戏编写脚本,但是那个游戏禁止在模拟器运行。一直以来我都在思考将使用 Python 编写的游戏脚本移植到 Android 上的可能性。最近我认为思路已经足够,因此我决定先以 baas 为例开始实验。
移植到 Android 上可能的优点:
可能的缺点:
思路
下面我将从几个方面分别讨论移植的思路与方案。
Python 本体
流行的 python android 方案有两种:
原本打算选择 2,因为更灵活,根据我下面的思路可能需要大量自定义 Java 代码。但是受限于 GUI 方案,这里只能选择 1。
值得注意的是,p4a 默认提供 Python 3.11,而 BAAS 使用 3.9。考虑到时间成本,这里暂定使用 3.11 版本,如果出现问题,后续再考虑能否可以改用 3.9。
GUI
BAAS 的 GUI 为 PyQt5 + pyqt fluent widgets。经过一番搜索,p4a 支持 PySide6,chaquopy 不支持任何 Qt 框架。尽管 PyQt5 似乎也可以部署到 Android 平台,但是资料久远且稀少,因此我决定将 BAAS 的 GUI 先行移植到 PySide6 上,再采用 p4a 方案。
目前使用的方案是:使用 qtpy + monkey patch。
qtpy 是一个 Python Qt 兼容层,抹平了 PyQt5/6 与 PySide6 之间的 API 差异。在引入 qtpy 后,通过 monkey patch,将对 PyQt5 的调用全部转发到 qtpy 上,然后由 qtpy 转发到 PySide6 上。
对于 pyqt fluent widgets,它本身就有 PySide6 版本,因此不需要做太多改动。
具体代码见 patch_window.py。
如果后续有机会,可以考虑将 BAAS 的 GUI 重构到 PySide6 或 qtpy 上。
OpenCV/numpy
p4a 支持 OpenCV 与 numpy。
OCR
BAAS 的 OCR 采用 IPC + 共享内存方案,但是很不幸,多进程与内存共享在 Android 上都不原生可用。如果坚持这种方案,可能需要大量修改 C++ 与 Python 代码,以采用 Android 平台上专有的内存共享方案。
因此,短期来看,我的解决方案是舍弃现有 ocr_server,改用 RapidOCR 的 Android 库,对其进行封装,让 Python 可以调用;长期来看,可以考虑(至少在 Android 上)舍弃 C++ 的多进程通信方案,做成 Python native 扩展。
adb
通常游戏脚本会大量依赖 adb 命令,特别是 adb shell 命令。一般情况下 adb shell 命令只有借助 adb 才能执行,无法在 Android 自身上执行,因为权限不够。
但是借助 Shizuku,普通的 Android APP 也可以拥有 shell 权限,因此脱离电脑执行 adb shell 命令是理论上可行的。
分辨率
目前有两种方案可以在手机上模拟出 1280x720 分辨率:
方案 1 会更简单,而且对现有控制代码的兼容性会更好,因为不涉及多显示器的处理。
但是采用方案 1,脚本执行时 BAAS 会被置于后台,存在被杀后台的风险,而方案 2 不存在这个问题。而且方案 2 理论上可以让用户在挂机的同时,干其他任何事情,只要手机性能允许。
截图
方案 2 在速度与性能上最佳,基本上录屏与投屏类 APP 都使用 MediaProjection API,不存在性能问题。
但是考虑到控制的问题,因此可能暂时会采用方案 3。
控制
方案 1 最简单;方案 2 功能最强大,但是需要用户手动授权,而且授权很容易掉,目前不清楚是否可以通过 shell 完成。
考虑到 #395 (comment) ,方案 3 如果可行,可能是目前的最佳选择。
其他
关于代码修改,根据上面的思路,会有很多地方需要针对平台特判。如果
进度与问题
GUI
目前我已成功移植 GUI,并且大部分功能正常可用,除了:
截图:



adb
目前已成功验证通过 Shizuku 调用 shell 命令可行。
下面的视频演示了 input swipe 命令。可以看到速度还是不错的,点击按钮后几乎瞬间就执行了滑动。
e9ec73c3a3bf925b2a8d4f460ae00018.mp4
分辨率
根据上面提到的 issue,已经有人成功验证了通过 wm size 修改分辨率可行。
控制
根据刚才的演示视频,input 方案可行。