Buildozer编译Android APK时Python包未部署到site-packages报错
ModuleNotFoundError: no module named 'myapp' 解决方法
项目结构
myapp-proj ├── buildozer.spec ├── main.py ├── myapp │ ├── cli │ │ ├── cli.py │ │ └── __init__.py │ ├── gui │ │ ├── gui.py │ │ └── __init__.py │ ├── __init__.py │ ├── myapp.egg-info │ │ ├── dependency_links.txt │ │ ├── entry_points.txt │ │ ├── PKG-INFO │ │ ├── requires.txt │ │ ├── SOURCES.txt │ │ └── top_level.txt │ └── utils │ ├── __init__.py │ └── logging.py └── setup.py
核心代码
main.py
import os import sys import traceback from myapp.gui import gui def main(): print(f"sys.path: {sys.path}") try: gui() except Exception as err: print(f"Critical exception. Error:\n{err}") traceback.print_exc() if __name__=='__main__': main()
gui.py
import kivy from kivy.app import App from kivy.uix.label import Label from myapp.utils.logging import log_generator log = log_generator(__name__) class AppGui(App): def build(self): return Label(text='myapp: hello world') def gui(): log.info(f"hello world") AppGui().run()
Buildozer配置与命令
编译运行命令
buildozer android debug deploy run ; buildozer android logcat | grep myapp
buildozer.spec配置
source.dir = . source.include_exts = py,png,jpg,kv,atlas source.include_patterns = main.py, myapp/__init__.py, myapp/gui/__init__.py, myapp/gui/gui.py, myapp/utils/__init__.py, myapp/utils/logging.py version = 0.1 requirements = python3,kivy orientation = portrait # # Android specific # fullscreen = 0 android.permissions = android.permission.INTERNET, (name=android.permission.WRITE_EXTERNAL_STORAGE;maxSdkVersion=18), android.permission.READ_EXTERNAL_STORAGE android.archs = arm64-v8a, armeabi-v7a android.allow_backup = True p4a.branch = develop android.no-byte-compile-python = True [buildozer] log_level = 2 warn_on_root = 1
错误现象
编译APK成功,但设备/模拟器运行时抛出错误:
ModuleNotFoundError: no module named 'myapp'
检查APK内部的assets/private.tar,发现仅包含main.py,缺失myapp子目录。构建日志提示:
Copying main.py's ONLY, since other app data is expected in site-packages.
但设备的site-packages目录中并未找到myapp包,设置p4a.setup_py=True也无法解决问题。
运行日志关键片段:
2024-03-06 13:51:17.390 5227-5299 python org.test.myapp I Initialized python 2024-03-06 13:51:17.390 5227-5299 python org.test.myapp I AND: Init threads 2024-03-06 13:51:17.400 5227-5299 python org.test.myapp I testing python print redirection 2024-03-06 13:51:17.415 5227-5299 python org.test.myapp I Android path ['.', '/data/user/0/org.test.myapp/files/app/_python_bundle/stdlib.zip', '/data/user/0/org.test.myapp/files/app/_python_bundle/modules', '/data/user/0/org.test.myapp/files/app/_python_bundle/site-packages'] 2024-03-06 13:51:17.417 5227-5299 python org.test.myapp I Android kivy bootstrap done. __name__ is __main__ 2024-03-06 13:51:17.417 5227-5299 python org.test.myapp I Run user program, change dir and execute entrypoint 2024-03-06 13:51:17.564 5227-5299 python org.test.myapp I Traceback (most recent call last): 2024-03-06 13:51:17.564 5227-5299 python org.test.myapp I File "main.py", line 5, in <module> 2024-03-06 13:51:17.567 5227-5299 python org.test.myapp I from myapp.gui import gui 2024-03-06 13:51:17.568 5227-5299 python org.test.myapp I ModuleNotFoundError: No module named 'myapp'
解决方法
方法1:修正source.include_patterns配置
当前配置仅指定单个文件,Buildozer不会递归复制目录结构。修改为递归包含myapp下所有Python文件:
source.include_patterns = main.py, myapp/**/*.py
方法2:移除source.include_patterns(推荐)
若无特殊文件过滤需求,直接删除source.include_patterns这一行,Buildozer会默认复制source.dir下所有符合source.include_exts的文件,自动包含整个myapp目录。
方法3:正确使用p4a.setup_py
如果需要通过setup.py打包,确保setup.py正确声明包结构:
from setuptools import setup, find_packages setup( name='myapp', version='0.1', packages=find_packages(), entry_points={ 'console_scripts': [ 'myapp = myapp.cli.cli:main', ], }, )
同时在buildozer.spec中启用:
p4a.setup_py = True
执行清理缓存后重新编译:
buildozer android clean buildozer android debug deploy run
验证步骤
修改配置后:
- 清理构建缓存:
buildozer android clean - 重新编译部署:
buildozer android debug deploy run - 检查APK的
assets/private.tar,确认myapp目录已被包含。
内容的提问来源于stack exchange,提问作者Bradley Evans
相关产品推荐
相关产品推荐

