参考:解决buildozer运行下载依赖包问题“fatal:无法访问‘https://github.com/kivy/python-for-android.git”解决过程
作为🀄️国人实在是太惨了,网络被封锁,使用 buildozer 打包还要面临网络封锁的问题
╰─➤ buildozer -v android debug 1 ↵
# Check configuration tokens
# Ensure build layout
# Create directory /Users/ponponon/Desktop/code/me/ideaboom/.buildozer
# Create directory /Users/ponponon/Desktop/code/me/ideaboom/bin
# Create directory /Users/ponponon/Desktop/code/me/ideaboom/.buildozer/applibs
# Create directory /Users/ponponon/Desktop/code/me/ideaboom/.buildozer/android/platform
# Create directory /Users/ponponon/Desktop/code/me/ideaboom/.buildozer/android/app
# Check configuration tokens
# Preparing build
# Check requirements for android
# Search for Git (git)
# -> found at /opt/homebrew/Cellar/git/2.49.0/bin/git
# Search for Cython (cython)
# -> found at /opt/homebrew/bin/cython
# Search for Java compiler (javac)
# -> found at /usr/bin/javac
# Search for Java keytool (keytool)
# -> found at /usr/bin/keytool
# Install platform
# Run ['git', 'clone', '-b', 'master', '--single-branch', 'https://github.com/kivy/python-for-android.git', 'python-for-android']
# Cwd /Users/ponponon/Desktop/code/me/ideaboom/.buildozer/android/platform
Cloning into 'python-for-android'...
# Run ['/Users/ponponon/.local/share/virtualenvs/ideaboom-B0dr_aXc/bin/python', '-m', 'pip', 'install', '-q', 'appdirs', 'colorama>=0.3.3', 'jinja2', 'sh>=1.10, <2.0; sys_platform!="win32"', 'build', 'toml', 'packaging', 'setuptools']
# Cwd None
# Apache ANT found at /Users/ponponon/.buildozer/android/platform/apache-ant-1.9.4
# Android SDK found at /Users/ponponon/.buildozer/android/platform/android-sdk
# Recommended android's NDK version by p4a is: 25b
# Android NDK is missing, downloading
# Downloading https://dl.google.com/android/repository/android-ndk-r25b-darwin.zip
Traceback (most recent call last):
File "/Users/ponponon/.local/share/virtualenvs/ideaboom-B0dr_aXc/bin/buildozer", line 8, in <module>
sys.exit(main())
File "/Users/ponponon/.local/share/virtualenvs/ideaboom-B0dr_aXc/lib/python3.10/site-packages/buildozer/scripts/client.py", line 13, in main
Buildozer().run_command(sys.argv[1:])
File "/Users/ponponon/.local/share/virtualenvs/ideaboom-B0dr_aXc/lib/python3.10/site-packages/buildozer/__init__.py", line 1024, in run_command
self.target.run_commands(args)
File "/Users/ponponon/.local/share/virtualenvs/ideaboom-B0dr_aXc/lib/python3.10/site-packages/buildozer/target.py", line 93, in run_commands
func(args)
File "/Users/ponponon/.local/share/virtualenvs/ideaboom-B0dr_aXc/lib/python3.10/site-packages/buildozer/target.py", line 103, in cmd_debug
self.buildozer.prepare_for_build()
File "/Users/ponponon/.local/share/virtualenvs/ideaboom-B0dr_aXc/lib/python3.10/site-packages/buildozer/__init__.py", line 172, in prepare_for_build
self.target.install_platform()
File "/Users/ponponon/.local/share/virtualenvs/ideaboom-B0dr_aXc/lib/python3.10/site-packages/buildozer/targets/android.py", line 615, in install_platform
self._install_android_ndk()
File "/Users/ponponon/.local/share/virtualenvs/ideaboom-B0dr_aXc/lib/python3.10/site-packages/buildozer/targets/android.py", line 438, in _install_android_ndk
self.buildozer.download(url,
File "/Users/ponponon/.local/share/virtualenvs/ideaboom-B0dr_aXc/lib/python3.10/site-packages/buildozer/__init__.py", line 658, in download
urlretrieve(url, filename, report_hook)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/urllib/request.py", line 1848, in retrieve
block = fp.read(bs)
File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/tempfile.py", line 483, in func_wrapper
return func(*args, **kwargs)
ValueError: read of closed file
怎么解决呢?
分析问题所在
首先我是挂了 t 的,所以我先用 requests 下载看看,是不是可以下载成功,看看是在 python 还是在网络
import urllib.request
url = "https://dl.google.com/android/repository/commandlinetools-mac-6514223_latest.zip"
local_filename = "commandlinetools-mac-6514223_latest.zip"
url="https://archive.apache.org/dist/ant/binaries/apache-ant-1.9.4-bin.tar.gz"
local_filename="apache-ant-1.9.4-bin.tar.gz"
try:
# 直接下载并保存文件
urllib.request.urlretrieve(url, local_filename)
print(f"文件已下载: {local_filename}")
except urllib.error.URLError as e:
print(f"下载失败: {e}")
发现是可以下载成功的
但是 buildozer 使用的是 urllib 下载的,所以问题出在 urllib 上吗?
于是写了一个 urllib 版本的
import urllib.request
url = "https://dl.google.com/android/repository/commandlinetools-mac-6514223_latest.zip"
local_filename = "commandlinetools-mac-6514223_latest.zip"
url="https://archive.apache.org/dist/ant/binaries/apache-ant-1.9.4-bin.tar.gz"
local_filename="apache-ant-1.9.4-bin.tar.gz"
try:
# 直接下载并保存文件
urllib.request.urlretrieve(url, local_filename)
print(f"文件已下载: {local_filename}")
except urllib.error.URLError as e:
print(f"下载失败: {e}")
发现也是可以正常下载的
那问题在于 buildozer 对 urllib 的使用方式了
所以深入扒一下 buildozer 的源代码
发现 buildozer 是使用 urlib 的 FancyURLopener.retrieve 下载的
class ChromeDownloader(FancyURLopener):
version = (
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 '
'(KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36')
urlretrieve = ChromeDownloader().retrieve
关于 FancyURLopener.retrieve 和直接使用 urllib.request.urlretrieve 的区别,我问了一下 ai
你代码的问题,核心原因还是出在 FancyURLopener().retrieve 是过时的老方法,它内部对临时文件(比如 tempfile)的处理方式不再适用于现代 Python 的文件流机制,导致
所以把 buildozer 里面的 retrieve 换一下就行?我验证一下
文件路径 site-packages/buildozer/__init__.py
结果就可以了
安装完成之后如下:
╰─➤ tree -L 4 ~/.buildozer
/Users/ponponon/.buildozer
├── android
│ └── platform
│ ├── android
│ │ └── platform
│ ├── android-ndk-r25b
│ │ ├── build
│ │ ├── CHANGELOG.md
│ │ ├── meta
│ │ ├── ndk-build
│ │ ├── ndk-gdb
│ │ ├── ndk-lldb
│ │ ├── ndk-stack
│ │ ├── ndk-which
│ │ ├── NOTICE
│ │ ├── NOTICE.toolchain
│ │ ├── prebuilt
│ │ ├── python-packages
│ │ ├── README.md
│ │ ├── shader-tools
│ │ ├── simpleperf
│ │ ├── source.properties
│ │ ├── sources
│ │ ├── toolchains
│ │ └── wrap.sh
│ ├── android-ndk-r25b-darwin.zip
│ ├── android-sdk
│ │ ├── build-tools
│ │ ├── commandlinetools-mac-6514223_latest.zip
│ │ ├── licenses
│ │ ├── platform-tools
│ │ └── tools
│ └── apache-ant-1.9.4
│ ├── apache-ant-1.9.4
│ └── apache-ant-1.9.4-bin.tar.gz
└── cache
题外话:「使用 FancyURLopener 有什么好处?为什么 buildozer 不直接使用 urllib.request.urlretrieve 而是要用 FancyURLopener?」想知道可以去问 AI
然后,buildozer 已经停止更新了,建议换一个打包工具了
https://pypi.org/project/buildozer/#history
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。