使用Buildozer编译Kivy安卓应用失败:Python3兼容性问题
问题描述
在MacBook Pro上通过Docker镜像编译Kivy安卓应用时,遭遇Python3兼容性问题,核心是pyjnius与python-for-android、Python 3.11不兼容。已尝试以下方案但均未解决:
- 在
buildozer.spec中指定Python 3.9.0 - 在Dockerfile中添加脚本替换pyjnius代码里的
long为int
相关配置与命令
Docker构建命令
docker build --no-cache --tag=kivy/buildozer .
buildozer.spec配置
[app] title = ASYSClayHandset package.name = asysclayhandset package.domain = org.test source.dir = . source.include_exts = py,png,jpg,kv,atlas version = 0.1 # Utiliser juste python3 et kivy requirements = python3,kivy [buildozer] log_level = 2 warn_on_root = 1 [app:android] android.api = 33 android.minapi = 21 android.ndk = 25b android.accept_sdk_license = True # UNE SEULE architecture android.archs = arm64-v8a
编译命令
docker run --interactive --tty --rm \ --volume "$PWD":/app \ kivy/buildozer bash -c "cd /app && rm -rf .buildozer && buildozer -v android debug 2>&1 | tee build.log"
编译报错信息
标准输出(STDOUT)
warning: jnius/jnius.pyx:102:0: The 'IF' statement is deprecated and will be removed in a future Cython version. Consider using runtime conditions or C macros instead. See https://github.com/cython/cython/issues/4310 Error compiling Cython file: ------------------------------------------------------------ ... score += 10 continue if r == 'S' or r == 'I': if isinstance(arg, int) or ( (isinstance(arg, long) and arg < 2147483648)): ^ ------------------------------------------------------------ jnius/jnius_utils.pxi:323:37: undeclared name not builtin: long
标准错误(STDERR)
# Command failed: ['/usr/bin/python3', '-m', 'pythonforandroid.toolchain', 'create', '--dist_name=asysclayhandset', '--bootstrap=sdl2', '--requirements=python3,kivy', '--arch=arm64-v8a', '--arch=armeabi-v7a', '--copy-libs', '--color=always', '--storage-dir=/app/.buildozer/android/platform/build-arm64-v8a_armeabi-v7a', '--ndk-api=21', '--ignore-setup-py', '--debug'] # ENVIRONMENT: # HOSTNAME = '6784017d022a' # PWD = '/app' # ANDROIDNDK = '/home/builduser/.buildozer/android/platform/android-ndk-r25b' # HOME = '/home/builduser' # ANDROID_HOME = '/opt/android-sdk' # TERM = 'xterm' # SHLVL = '0' # PATH = '/home/builduser/.buildozer/android/platform/apache-ant-1.9.4/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/android-sdk/cmdline-tools/latest/bin:/opt/android-sdk/platform-tools' # DEBIAN_FRONTEND = 'noninteractive' # OLDPWD = '/app' # _ = '/usr/local/bin/buildozer' # LC_CTYPE = 'C.UTF-8' # PACKAGES_PATH = '/home/builduser/.buildozer/android/packages' # ANDROIDSDK = '/home/builduser/.buildozer/android/platform/android-sdk' # ANDROIDAPI = '31' # ANDROIDMINAPI = '21' # # Buildozer failed to execute the last command # The error might be hidden in the log above this error # Please read the full log, and search for it before # raising an issue with buildozer itself. # In case of a bug report, please add a full log with log_level = 2
可行解决方案
1. 锁定兼容的Python版本与依赖版本
问题根源是指定python3会默认拉取最新版(3.11),而旧版pyjnius不支持。修改buildozer.spec的requirements,明确指定兼容的版本组合:
requirements = python3.9, kivy==2.1.0, pyjnius==1.4.0
同时确保android.ndk与Python版本匹配:Python 3.9推荐搭配NDK 23b(而非25b),修改buildozer.spec:
[app:android] android.ndk = 23b
2. 正确修改pyjnius代码(Dockerfile方案)
之前的脚本替换可能未命中正确文件路径,在Dockerfile中添加以下内容,确保编译时替换pyjnius中的long为int:
RUN pip install --upgrade cython # 编译前替换pyjnius中的long关键字 RUN find /home/builduser/.buildozer/android/packages -name "jnius_utils.pxi" -exec sed -i 's/isinstance(arg, long)/isinstance(arg, int)/g' {} \;
注意:要在执行buildozer命令前执行该替换操作,也可通过buildozer的pre-build钩子实现。
3. 使用Kivy官方稳定版Docker镜像
无需自行构建镜像,直接使用Kivy官方预配置的稳定镜像,避免环境不一致问题:
docker run --interactive --tty --rm \ --volume "$PWD":/app \ kivy/buildozer:stable bash -c "cd /app && rm -rf .buildozer && buildozer -v android debug 2>&1 | tee build.log"
替代编译方案
- GitHub Actions自动编译:配置GitHub Actions工作流,利用官方提供的Kivy编译环境,无需本地Docker,规避环境依赖问题。
- BeeWare Briefcase:如果Buildozer流程问题较多,可尝试BeeWare的Briefcase工具,它支持将Python应用打包为安卓APK,兼容Kivy应用(需微调部分代码适配)。
内容的提问来源于stack exchange,提问作者charlifumi
相关产品推荐
相关产品推荐

