使用Buildozer打包KivyMD安卓应用时NLTK无法运行问题求助
故障核心原因
- NLTK的
word_tokenize功能依赖punkt语料包,本地开发环境你已经提前下载过该语料,所以运行正常。但安卓打包时你没有将依赖的NLTK语料包打包进APK,安卓环境无法自动下载语料,调用相关接口时直接触发崩溃。 - 你将NLTK相关调用写在模块顶层,APP还未完成初始化、未配置NLTK语料路径时就执行了相关逻辑,进一步加剧崩溃问题。
修复步骤
1. 准备NLTK语料包
本地先执行代码下载需要的语料到项目根目录的nltk_data文件夹:
import nltk nltk.download('punkt', download_dir='./nltk_data') # 后续用到其他NLTK语料也按同样方式提前下载到该目录
2. 修改main.py代码
把NLTK初始化、语料路径配置、业务逻辑移到APP初始化完成后的方法内,不要放在模块顶层:
import kivymd from kivymd.app import MDApp from kivymd.uix.screen import Screen from kivymd.uix.label import MDLabel import nltk import json import os from nltk.stem.lancaster import LancasterStemmer from android.permissions import request_permissions, Permission class MainApp(MDApp): def build(self): # 申请必要的存储权限 request_permissions([Permission.READ_EXTERNAL_STORAGE, Permission.WRITE_EXTERNAL_STORAGE]) # 配置NLTK语料路径 nltk_data_path = os.path.join(self.user_data_dir, 'nltk_data') nltk.data.path.append(nltk_data_path) # 业务逻辑移到此处执行 with open("intents.json") as file: data = json.load(file) words = str(nltk.word_tokenize(str([data["intents"][0]["patterns"][0]]))) stemmer = LancasterStemmer() stemmertest = stemmer.stem('addition') screen = Screen() label = MDLabel(text=words, pos_hint={'center_x': 0.7, 'center_y': 0.3}) label2 = MDLabel(text=stemmertest, pos_hint={'center_x': 0.7, 'center_y': 0.5}) screen.add_widget(label) screen.add_widget(label2) return screen if __name__ == "__main__": MainApp().run()
3. 修改buildozer.spec配置
- 把
nltk_data文件夹加入打包的资产目录:android.add_assets = nltk_data/ - 补充NLTK依赖的隐式导入包,避免Buildozer打包时裁剪掉相关模块:
android.add_packages = nltk.tokenize,nltk.stem
4. 异常兼容处理
如果首次启动提示找不到语料,可增加一段初始化逻辑,把assets目录下的nltk_data递归复制到APP私有可读写目录self.user_data_dir下,再配置NLTK路径即可。
内容的提问来源于stack exchange,提问作者Tanish
相关产品推荐
相关产品推荐

