↓内容,为Ai自动生成,仅作阅读分享!
------
—— 从Windows的 .exe到安卓的 .apk,保姆级打包教程
你写好的Python脚本,如何变成别人双击就能跑的程序?如何变成手机上能安装的App?这篇文章,手把手带你搞定。
写在前面
作为一名Python开发者,你一定遇到过这样的场景:
· 你把一个自动化脚本写好了,想发给不懂编程的同事用,对方却说“我没有Python环境”;
· 你用Python写了一个小工具,想在手机上运行,却不知道怎么转换成apk;
· 你听说过PyInstaller和Buildozer,但总觉得打包过程神秘又复杂。
别担心,今天这篇“保姆级”教程,将从零开始,带你彻底掌握Python脚本的两种主流打包方式:
1. Windows下的exe打包 —— 使用PyInstaller,让程序脱离Python环境运行。
2. 安卓下的apk打包 —— 使用Kivy + Buildozer,把Python代码变成手机App。
全程无废话,每一步都有解释,哪怕是完全没接触过打包的小白,也能跟着操作成功。
---
第一部分:Windows下的exe打包 —— PyInstaller详解
1.1 为什么需要打包?
Python脚本通常依赖解释器和第三方库。如果直接把.py文件发给别人,对方需要安装Python、安装依赖、在命令行里运行……这对普通用户极不友好。打包成.exe后,双击即可运行,就像使用普通软件一样。
1.2 PyInstaller是什么?
PyInstaller是最流行的Python打包工具之一。它能够分析你的脚本,自动收集所有依赖(包括Python解释器、导入的库、动态链接库等),将它们打包成一个独立的可执行文件(Windows下为.exe,Linux下为二进制文件,macOS下为.app)。
1.3 安装PyInstaller
打开命令提示符(cmd)或PowerShell,执行:
```bash
pip install pyinstaller
```
如果你使用虚拟环境,记得先激活环境再安装。
验证是否安装成功:
```bash
pyinstaller --version
```
看到版本号(如5.13.0)即为成功。
1.4 第一个打包实例:单文件exe
假设你有一个简单的Python脚本 hello.py:
```python
print("Hello, 世界!")
input("按回车键退出...")
```
在脚本所在目录打开cmd,执行:
```bash
pyinstaller -F hello.py
```
参数说明:
· -F 或 --onefile:打包成单个exe文件。
· 如果不加-F,默认会生成一个文件夹,里面包含exe和一堆依赖文件。
执行后,你会看到类似这样的输出:
```
...
Building EXE from EXE-00.toc completed successfully.
```
打包好的exe位于 dist 文件夹下,文件名就是 hello.exe。
测试一下:双击 hello.exe,弹出一个黑色窗口,显示“Hello, 世界!”,按回车键关闭。成功!
1.5 常用打包选项详解
选项 作用
-F / --onefile 打包成单个exe文件
-D / --onedir 打包成一个文件夹(默认方式)
-w / --windowed 不显示控制台窗口(适用于GUI程序)
-i / --icon 指定exe的图标,如 -i myicon.ico
--name 指定输出文件名,如 --name myapp
--add-data 添加额外的数据文件(如图片、配置文件)
--hidden-import 手动添加PyInstaller未能自动发现的导入模块
--upx-dir 使用UPX压缩可执行文件,减小体积
示例:打包一个带GUI的程序(不显示黑窗口)
假设你有一个使用Tkinter或PyQt的图形界面程序 gui_app.py:
```bash
pyinstaller -F -w -i logo.ico --name "我的工具" gui_app.py
```
这样生成的exe双击后不会弹出烦人的cmd窗口,看起来更像一个正经软件。
1.6 处理依赖与隐藏导入
PyInstaller自动分析 import 语句,但有些库是动态导入的(例如importlib.import_module),或者通过字符串加载模块(如__import__('some_module')),这些会被漏掉,导致打包后运行报错 ModuleNotFoundError。
解决方案:使用 --hidden-import 手动添加。
例如,如果你使用了 pandas 的某些插件,可以这样:
```bash
pyinstaller -F --hidden-import pandas._libs.tslibs.timedeltas my_script.py
```
更好用的方法:编写spec文件。
生成spec文件:
```bash
pyinstaller --name myapp --onefile my_script.py
```
此时会在当前目录生成 myapp.spec。用文本编辑器打开它,找到 Analysis 部分,修改 hiddenimports:
```python
a = Analysis(
['my_script.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=['pandas._libs.tslibs.timedeltas', 'sklearn.utils._cython_blas'],
hookspath=[],
...
)
```
然后运行:
```bash
pyinstaller myapp.spec
```
1.7 打包时如何包含资源文件(图片、配置文件等)
如果你的程序需要读取外部的图片、字体、配置文件,直接打包后exe会找不到它们,因为资源没有被复制到exe里。
方法一:使用 --add-data
```bash
pyinstaller -F --add-data "images/logo.png;images" --add-data "config.ini;." my_script.py
```
解释:
· 源路径;目标路径:Windows用分号;,Linux/macOS用冒号:。
· images/logo.png会被放到exe运行时的 images 文件夹下。
· 在代码中读取资源时,需要获取临时解压目录。推荐使用下面的通用函数:
```python
import sys
import os
def resource_path(relative_path):
"""获取资源的绝对路径,兼容开发环境和打包后的exe"""
try:
# PyInstaller创建临时文件夹,将路径存储在_MEIPASS中
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
# 使用示例
logo_path = resource_path("images/logo.png")
```
方法二:在spec文件中配置datas
```python
a = Analysis(
...
datas=[('images/*.png', 'images'), ('config.ini', '.')],
...
)
```
1.8 常见错误与解决方法
错误现象 可能原因 解决办法
打包成功,运行闪退 缺少依赖或代码有bug 在cmd中运行exe,看错误输出;或者不用-w先看控制台
Failed to execute script xxx 隐藏导入未找到 使用--hidden-import或修改spec
文件路径找不到 资源未正确打包或路径写死 使用resource_path函数动态获取路径
打包后exe体积巨大 包含了不必要的库 使用虚拟环境,只安装必需的库;或用UPX压缩
杀毒软件报毒 PyInstaller打包特征被误判 添加信任;或用其他工具(如Nuitka)打包
1.9 进阶:使用UPX压缩exe
UPX(Ultimate Packer for eXecutables)能显著减小exe体积。下载UPX(https://upx.github.io/)并将 upx.exe 放在系统PATH中,或者放在PyInstaller目录下。然后正常打包,PyInstaller会自动调用UPX压缩。
也可以手动指定:
```bash
pyinstaller --upx-dir "C:\upx" -F my_script.py
```
---
第二部分:安卓下打包apk —— Kivy + Buildozer 全攻略
2.1 为什么不能用PyInstaller直接打apk?
PyInstaller的目标平台是桌面操作系统(Windows、Linux、macOS),生成的exe或二进制文件无法在安卓的Linux内核上直接运行,因为安卓的用户空间环境(如Bionic libc、没有X11、没有标准桌面库)与桌面Linux完全不同。
要将Python程序移植到安卓,必须:
· 提供一个能在安卓上运行的Python解释器(通常是编译为共享库的CPython);
· 将所有依赖库也编译为安卓兼容的.so文件;
· 建立一个Java壳(Activity)来启动Python代码;
· 打包成APK。
Buildozer 正是这样一个工具,它自动化了上述复杂流程。
2.2 环境准备:Windows用户必看(WSL2)
Buildozer 只在Linux环境下工作。如果你是Windows用户,最佳方案是安装 WSL2(Windows Subsystem for Linux)。
步骤1:启用WSL2
以管理员身份打开PowerShell,执行:
```powershell
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```
重启电脑。
步骤2:设置WSL2为默认版本
重启后,以管理员身份再次打开PowerShell:
```powershell
wsl --set-default-version 2
```
步骤3:安装Ubuntu
```powershell
wsl --install -d Ubuntu
```
安装完成后,启动Ubuntu(在开始菜单中可以找到),首次启动会要求创建用户名和密码。记住这个密码,后面sudo操作会用到。
步骤4:更新Ubuntu并安装必要工具
在Ubuntu终端中执行:
```bash
sudo apt update && sudo apt upgrade -y
sudo apt install -y git zip unzip openjdk-11-jdk python3-pip
```
验证Java安装:
```bash
java --version
```
应该显示 openjdk 11 的信息。
步骤5:打通Windows与Ubuntu的文件共享
Buildozer需要访问你在Windows下写的Python代码。最简单的方法是将项目放在 Windows的用户目录 下,然后在Ubuntu中通过 /mnt/c/Users/你的用户名/ 访问。
例如,在Windows中创建 C:\Users\你的用户名\kivy_projects,在Ubuntu中:
```bash
cd /mnt/c/Users/你的用户名/kivy_projects
```
这样两边都能读写同一份文件。
2.3 安装Buildozer和Kivy
在Ubuntu终端中执行:
```bash
pip3 install --user --upgrade buildozer kivy
```
安装完成后,将~/.local/bin添加到PATH(通常已经自动添加,可以重启终端生效)。
验证:
```bash
buildozer --version
```
如果提示找不到命令,可以手动添加:
```bash
echo 'export PATH="$PATH:$HOME/.local/bin"' >> ~/.bashrc
source ~/.bashrc
```
2.4 编写一个简单的Kivy应用程序
Kivy是Python的跨平台GUI框架,专门为多点触控设计。要打包成APK,你的程序必须基于Kivy(或其他支持安卓的框架如BeeWare)。
创建一个项目文件夹,例如 myfirstapp,在其中新建 main.py:
```python
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
class MyApp(App):
def build(self):
layout = BoxLayout(orientation='vertical', padding=50, spacing=10)
self.label = Label(text='欢迎使用我的App', font_size='30sp')
btn = Button(text='点击我', size_hint=(1, 0.3))
btn.bind(on_press=self.on_button_press)
layout.add_widget(self.label)
layout.add_widget(btn)
return layout
def on_button_press(self, instance):
self.label.text = '你点击了按钮!'
if __name__ == '__main__':
MyApp().run()
```
这是一个非常简单的应用:一个标签,一个按钮,点击按钮会改变标签文字。
2.5 初始化Buildozer配置
在项目文件夹下(包含main.py),执行:
```bash
buildozer init
```
会生成一个 buildozer.spec 文件,这是打包的配置文件,非常重要。
2.6 详解buildozer.spec核心配置
用nano或vim打开buildozer.spec,找到以下关键配置项并修改:
```ini
[app]
# 应用标题(手机桌面上显示的名称)
title = My First App
# 包名(唯一标识,格式类似域名倒序)
package.name = myfirstapp
# 域名(与package.name组合成完整包名,如 org.example.myfirstapp)
package.domain = org.example
# 源代码目录(通常就是当前目录)
source.dir = .
# 入口文件(必须是Python文件)
source.include_exts = py,png,jpg,kv,atlas,ttf
# 需要的Python库(用逗号分隔,不要有空格)
requirements = python3,kivy
# 安卓目标SDK版本(推荐33或34)
android.api = 33
# 安卓NDK版本(推荐25b或更稳定版本)
android.ndk = 25b
# 安卓最低SDK版本(一般19即可兼容Android 4.4+)
android.minapi = 21
# 是否允许应用访问互联网(如果需要网络,设为True)
android.permissions = INTERNET
# 图标文件(可选,放入项目目录下)
icon.filename = %(source.dir)s/icon.png
# 启动画面(可选,图片会在应用启动时显示)
presplash.filename = %(source.dir)s/presplash.png
```
特别提醒:
· requirements 必须包含 python3 和 kivy,如果有其他库(如numpy、requests),也要加上,用逗号分隔:requirements = python3,kivy,numpy,requests
· 如果要用到Kivy的扩展,比如KivyMD,则写成 requirements = python3,kivy,kivymd
· 版本号建议锁定,例如 python3==3.9.5,kivy==2.1.0,避免因版本升级导致不兼容。
2.7 开始打包:生成APK
在项目目录下执行:
```bash
buildozer -v android debug
```
参数说明:
· -v:输出详细日志,方便排查错误。
· android debug:打包成debug版本的APK(未签名,可直接安装)。
首次打包非常漫长(可能半小时到一小时),因为Buildozer会下载:
· Android SDK(几百MB)
· Android NDK(几百MB)
· 各种编译工具链
· Python的安卓版本
· 所有requirements中列出的库源码并编译
请保持网络通畅,耐心等待。强烈建议配置国内镜像源(见下文优化章节),否则可能因为网络问题失败。
成功打包后,APK文件会出现在 bin 目录下,名称类似 myfirstapp-0.1-armeabi-v7a-debug.apk。
2.8 在手机上安装并运行
将APK文件通过USB或微信等工具传输到安卓手机上,点击安装。如果手机提示“禁止安装未知来源应用”,请去设置中允许。
安装后打开,你应该能看到刚才写的界面:一个标签“欢迎使用我的App”,一个按钮“点击我”。点击按钮,标签文字变为“你点击了按钮!”。
2.9 优化与调试(保姆级补充)
🀄️ 解决中文显示问题
Kivy默认字体不含中文,会出现方框乱码。解决方案:打包时携带中文字体文件。
1. 下载一个开源中文字体,如“阿里巴巴普惠体”、“思源黑体”等,重命名为 chinese.ttf。
2. 将 chinese.ttf 放在项目目录(与main.py同级)。
3. 在 main.py 的 build 方法之前,注册字体:
```python
from kivy.core.text import LabelBase
LabelBase.register(name='ChineseFont', fn_regular='chinese.ttf')
```
4. 在所有需要显示中文的控件中指定 font_name='ChineseFont'。
```python
self.label = Label(text='欢迎使用我的App', font_name='ChineseFont', font_size='30sp')
```
5. 在 buildozer.spec 中确保 source.include_exts 包含 ttf(默认已包含)。
⚡️ 加速打包(国内镜像源配置)
系统源加速(Ubuntu/WSL):
```bash
sudo sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list
sudo apt update
```
Buildozer镜像加速:编辑 buildozer.spec,找到 [buildozer] 部分,添加:
```ini
[buildozer]
pypi_mirror = https://pypi.tuna.tsinghua.edu.cn/simple
android_sdk_url = https://mirrors.tuna.tsinghua.edu.cn/android/repository/
android_ndk_url = https://mirrors.tuna.tsinghua.edu.cn/android/ndk/
```
🐞 调试:查看手机日志
如果你的App在手机上闪退,可以通过ADB查看日志。
1. 在手机上开启“开发者选项”和“USB调试”。
2. 在Ubuntu中安装ADB:
```bash
sudo apt install adb
```
3. 连接手机(手机上允许USB调试)。
4. 运行:
```bash
buildozer android logcat
```
或过滤Python相关日志:
```bash
buildozer android logcat | grep python
```
日志会显示Python报错的具体信息,比如缺少某个模块、语法错误等。
🔧 常见错误及解决
错误 原因 解决方案
sdkmanager not found SDK下载不完整或路径错误 删除 ~/.buildozer 文件夹,重新运行 buildozer android debug
No module named 'xxx' requirements中遗漏了依赖 在requirements中添加该库,并删除.buildozer重新打包
NDK version mismatch NDK版本不兼容 在spec中指定android.ndk = 25b或23b
打包成功但安装时提示“解析包错误” APK损坏或签名问题 重新打包,或者将.android debug签名删除后重建
手机运行时屏幕一直黑 可能是缺少OpenGL支持或代码错误 查看logcat日志排查
2.10 关于Kivy与KV语言的小贴士
在本文的示例中,我们完全用Python代码写UI。但Kivy推荐使用 KV语言 来分离界面和逻辑。KV语言是一种声明式语法,类似CSS+HTML的混合体。
为什么要学KV?
· 界面代码简洁优雅,维护方便。
· 支持属性绑定(数据变化自动更新UI)。
· 更易于实现复杂布局和动画。
一个简单的KV示例:
创建一个 myapp.kv 文件(注意文件名必须与App类名去掉App且小写,即MyApp -> myapp.kv):
```kv
BoxLayout:
orientation: 'vertical'
padding: 50
spacing: 10
Label:
id: my_label
text: '欢迎使用我的App'
font_size: '30sp'
font_name: 'chinese.ttf'
Button:
text: '点击我'
size_hint: (1, 0.3)
on_press: app.on_button_press()
```
然后在Python中只需:
```python
from kivy.app import App
class MyApp(App):
def on_button_press(self):
self.root.ids.my_label.text = '你点击了按钮!'
if __name__ == '__main__':
MyApp().run()
```
KV文件中的 app.on_button_press() 调用了Python类中的方法,self.root.ids.my_label 访问了KV中定义的控件。这就是Kivy的“互生互成”——Python管逻辑,KV管界面。
---
第三部分:总结与适用场景
3.1 两种打包方式的对比
特性 PyInstaller (exe) Buildozer (apk)
目标平台 Windows / Linux / macOS Android
界面框架要求 任意(Tkinter/PyQt/Kivy等) 必须基于Kivy或支持安卓的框架
打包难度 ★☆☆☆☆ ★★★★☆
打包速度 几秒到几分钟 首次30分钟以上,后续几分钟
输出体积 几十MB 几十到上百MB
适用场景 向Windows用户分发工具、小游戏 发布手机App、触控应用
3.2 学习建议
1. 先从PyInstaller入手:它简单直接,能让你快速理解“打包”的基本概念。
2. 再挑战Buildozer:需要一点Linux基础,但跟着本文步骤走,成功率很高。
3. 如果想认真做安卓App:建议系统学习Kivy和KV语言,并研究Buildozer的spec高级配置(如自定义编译选项、添加第三方aar等)。
3.3 写在最后
Python的灵活性让它不仅能做数据分析、后端开发,还能通过打包工具变成普通人也能使用的桌面软件和手机App。希望这篇“保姆级”教程能够帮助你把创意变成可交付的产品。
如果在实际操作中遇到任何问题,欢迎在评论区留言(本文假设发布在公众号上),我会尽力解答。
动手试一试:拿起你以前写的一个小脚本,先用PyInstaller打成exe,再用Kivy重写一个简单界面打成apk。你会发现,打包并没有想象中那么神秘。
祝打包顺利,早日做出属于自己的软件!
本文约6000字,从环境搭建到常见错误,从PyInstaller到Buildozer,力求每一步都清晰可操作。如果觉得有用,欢迎转发给需要的朋友。
------