完整教程:Python - PEP 738 – 将 Android 添加为支持平台
2025-11-15 10:42 tlnshuju 阅读(0) 评论(0) 收藏 举报Python - PEP 738 – 将 Android 添加为支持平台
摘要
本 PEP 提议在 CPython 中将 Android 添加为支持平台。初步目标是在 Python 3.13 实现 Android 的 Tier 3 支持。
本 PEP 基于PEP 730(Russell Keith-Magee 的“将 iOS 添加为承受平台”),涵盖了许多类似障碍。两平台的显著差异可通过搜索“iOS”一词找到。
动机
在过去的 15 年里,移动平台在计算领域的重要性日益提升。Android 是运行在约70% 移动设备上的操作系统。然而,CPython 目前并不正式支撑 Android。
Chaquopy、BeeWare 和 Kivy等项目多年来一直拥护 Android,并且相关应用已被 Google Play 商店接受。这证明了技术上完全可行。
对于 Python 的未来来说,能在主流平台广泛使用至关重要。否则,潜在用户会转向那些已经支持这些平台的其他语言。尤其在教育领域,下一代开发者已经越来越多地使用移动平台而不是桌面设备。
原理
通用
Android 基本是 POSIX 平台,基于 Linux 内核,使用 ELF 二进制格式。但它不应用 glibc,而是自带名为 Bionic 的 C 库,因此即使架构相同,也通常与其他 Linux 发行版二进制不兼容。Android 还拥有独特的文件系统布局,与其他 Unix 不同。
不过,Android 对 Linux 的源代码兼容性相当好。早期 C 库很不完整,但到 2014 年已核心补齐。此后,绝大多数为 Linux 编写的 C 代码都能为 Android 编译,只要不直接访问硬件或底层系统服务。
CPython 也是如此,尽管未正式拥护 Android,但自 3.6 版起,仅需极少补丁即可为 Android 编译。
操作系统版本
每个 Android 版本有三种标识方式:
- 常规点分版本号(近年多为整数)
- 顺序递增的“API level”(开发文档中最常用)
- 字母糖果主题的代号(市场推广已不用,但创建文档仍见)
三者无固定对应规则,需查表。
每年有新主版本,但能否升级完全由设备厂商决定,许多厂商在用户淘汰设备前已停止提供更新。例如,截至 2023 年 10 月,仍有安全更新的最老版本是 API 30,但据Google 官方统计,仅 60% 设备运行该版本或更新版本。
因此,建议 Python 3.13 的最低支持 Android 版本为 5.0(API 21,2014 年发布),覆盖 99% 的活跃设备。
开发工具
Android 开发工具在 Linux(x86_64)、Windows(x86_64)和 macOS(x86_64、ARM64)上均等支撑。CPython 相关主要设备有:
- NDK(Native Development Kit):包含 C/C++ 编译器(clang)、链接器(lld)及所有系统库头文件。
- 不同 NDK 版本编译的库间二进制兼容性很好,但为保证可复现性,一个 Python 版本应始终用同一 NDK 版本。Python 3.13 建议用 NDK r26。
- 每个 NDK 可针对多种 Android 版本(API 21~34)。通常为老版本编译的二进制在新版本上也能运行,除非有安全原因例外。
- Gradle:用于构建可部署应用。
- 模拟器:基于 QEMU,可在开发机上模拟 Android 设备。与 iOS 不同,模拟器使用与真机相同的 ABI,可运行同样的二进制。
上述软件可在命令行或 Android Studio(基于 IntelliJ IDEA)中利用。
架构
Android 当前支持 4 种架构,命名如下:
armeabi-v7aarm64-v8ax86x86_64
绝大多数真机用 ARM 架构,x86/x86_64 仅在模拟器用。
Python 3.13 Tier 3 仅支持 64 位平台(arm64-v8a 和 x86_64):
x86自 2020 年起不再支持开发,也无新模拟器镜像。armeabi-v7a现仅占活跃设备不到 10%,且持续下降。- 该架构无原生模拟器主机(ARM64 Mac 不支撑 ARM32),跨架构模拟器性能和稳定性差,自 2016 年起未更新镜像。
- 但在手表和超低端手机仍有用,若有需要可将来补充协助。
即使 32 位架构不被官方支持,也不应做出妨碍下游工程构建 32 位包的更改。
应用生命周期
由操作系统启动虚拟机运行系统提供的可执行文件。应用中的 Java 代码可通过 JNI 加载动态库并调用本地代码。就是Android 应用主要用 Java 或 Kotlin 编写。应用本身不提供可执行文件,而
与 iOS 不同,Android 支持创建子进程,但仅可在特定位置运行,且这些位置运行时不可写。长时间运行的子进程官方并不推荐,未来也可能不再支持。
Android 给出命令行 shell,但仅供开发者使用,普通用户无法访问。
因此,推荐的 Python 运行方式是在主进程加载 libpython3.x.so 动态库。不会正式支持 python3.x 可执行文件。
规范
工作范围
本项工作的重点是在 Android 上搭建类似于Windows 可嵌入包的功能,即一组可被开发者集成到应用中的编译库,无需安装器。
将 Android 加入 Tier 3 只需支持用未经补丁的 CPython 源码编译出 Android 兼容包,无需 python.org 官方分发 Android 构建(但未来可补充)。
Android 构建流程与其他 POSIX 平台一致,使用 configure/Makefile 系统,须在 POSIX 平台(Linux 或 macOS)构建。
将提供 Gradle 项目用于运行 CPython 测试套件,并自动化测试 app 构建、模拟器启动、安装及执行。
链接方式
如应用生命周期所述,Python 将作为动态库 libpython3.x.so 集成进 app,可用 dlopen 加载。
与 Linux 不同,Android 即使指定 RTLD_GLOBAL,也不会自动用已 dlopen 的库解析后续库的重定位符。因此所有 Python 扩展模块在 Android 上构建时必须显式链接 libpython3.x.so。
扩展模块若链接 libpython3.x.so,则不能被静态链接 libpython3.x.a 的可执行文件加载。因此,Android 不支持静态 libpython3.x.a,与 Windows 策略一致。
这种方式允许用 -Wl,--no-undefined 在构建时检测缺失符号,提升开发效率。
与 iOS 不同,Android 可从任意位置加载动态库,因此 .py、.pyc 和 .so 可同目录共存,由标准 importer 处理。
标准库
不帮助的模块
因底层 C API 不可用,以下标准库模块不帮助:
curses和readlinedbm.gnu与dbm.ndbmgrpmultiprocessing– 虽然允许子进程,但 Android 不支持 System V IPC API。tkinter和turtle– 需 Android 版 Tk,官方不支持。
sys
sys.platform 返回 "android"。虽然 Android 基于 Linux,但差异足够大,值得单独命名。
嵌入 Android app 时,C 层 stdio 未连接到任何输出。因此 sys.stdout 和 sys.stderr 将重定向到系统 Logcat,可用开发工具查看。sys.stdin 永远返回 EOF。
platform
platform 模块大部分值与 os.uname() 返回相同,例外如下:
platform.system()– 返回"Android",而非"Linux"platform.release()– 返回 Android 版本字符串(如"14"),而非 Linux 内核版本
此外将新增 platform.android_ver(),返回包含以下内容的 namedtuple:
release– 设备的 Android 版本字符串(如"14")api_level– 设备的 API level 整数(如34)manufacturer– 设备制造商字符串(如"Google")model– 设备型号字符串(如"Pixel 7")device– 设备设备名字符串(如"panther")is_emulator– 若为模拟器则为 True,真机为 False
model 和 device 哪个更独特、哪个更接近市场名因厂商而异。
os
os.uname() 返回 POSIX uname() 原始结果:
sysname–"Linux"release– Linux 内核版本(如"5.10.157-android13-4-00003-gdfb1120f912b-ab10994928")
即 os 作为底层 API,platform 提供更高阶通用信息。
CI 资源
因模拟器和真机 ABI 一致、系统二进制高度相似,模拟器测试足够。x86_64 模拟器可在 Linux、macOS、Windows 上运行,ARM64 模拟器仅限 ARM64 Mac。
Anaconda已承诺提供运行 Android buildbot 的物理硬件,包括 Linux x86_64 和 macOS ARM64,覆盖两种运行和构建架构。
CPython 目前不在 GitHub Actions 上测试 Tier 3 平台,若未来协助,Linux/macOS runner 也可运行 Android 模拟器。macOS ARM64 runner 自 2024 年 1 月起对所有公开仓库免费开放。
打包
Android wheel 标签格式为 android_<api-level>_<abi>,如:
android_21_arm64_v8aandroid_21_x86_64
其中 <api-level> 见操作系统版本,代表构建 wheel 时选定的最低 Android 版本。pip 等设备应像 macOS 标签一样解释,即 app 最低 API level 为 N 时可用 N 或更低的 wheel。
该格式源自 Chaquopy 项目,目前维护的wheel 仓库标签范围覆盖 API 16~21。
但依赖少数爱好者维护生态不可持续。只有主流库常规发布 Android wheel,社区才能真正普及 Python on Android。
因此,需详细文档说明如何在 CI 和发布工具中添加 Android 构建。为crossenv 和 cibuildwheel等工具添加 Android 支持是一种方式。
该 Android wheel 标签应被 PyPI 接受。
PEP 11 更新
PEP 11将新增两个受拥护 Android ABI。Autoconf 已识别为:
aarch64-linux-androidx86_64-linux-android
Petr Viktorin 将作为这些 ABI 的核心团队联系人。
向后兼容性
新增平台不会引入 CPython 本身的向后兼容性问题。但历史上协助 CPython 的项目(如 BeeWare、Kivy)若与最终补丁不一致,可能受影响。
安全影响
新增平台不会带来安全影响。
如何教学
本 PEP 教学内容面向两类开发者:
- 应用开发者:需了解如何将 Python 集成进 Android app,包括自己的 Python 代码和依赖包,以及运行方式。文档会类似Windows 可嵌入包。但建议大多数开发者使用Briefcase、Chaquopy、Buildozer等高层设备,这些工具已有完善文档。
- 带二进制组件的包开发者:需了解如何为 Android 构建并发布自己的包(见打包)。
参考实现
Chaquopy 仓库包含参考补丁和构建脚本。需与 Chaquopy 其他部分解耦后才能上游合并。
Briefcase提供了在 Android 设备和模拟器上执行测试的参考实现。Toga Testbed是用 GitHub Actions 在 Android 模拟器上跑测试的示例。
被拒绝方案
对原 platform.android_ver() 规范的更改包括:
- 移除
min_api_level字段,因为它不是当前设备属性,可由sys.getandroidapilevel()查询。 - 增加
is_emulator字段,因测试过程中发现部分问题特定于模拟器。
版权
本文档可置于公有领域或 CC0-1.0-Universal 许可下,以更宽松者为准。
原文地址:https://peps.python.org/pep-0738/
浙公网安备 33010602011771号