Kivy应用编译到Android后窗口尺寸异常及黑屏问题求助
问题
应用在Windows系统运行正常,但通过Buildozer编译到Android平台后启动黑屏,Logcat返回错误:
[SurfaceView[kcb_sinner.kcb/org.kivy.android.PythonActivity]#1]9f:0,a:0) rejecting buffer:active_size=720x1280, requested_size=720x1280 buffer{size=720x1184 transform=0}
代码片段
import sqlite3 from curse import Recipe from kivy.config import Config Config.set("graphics","width","700") Config.set("graphics","height","200") Config.write() from kivy.app import App from kivy.uix.label import Label from kivy.uix.button import Button from kivy.uix.textinput import TextInput from kivy.uix.boxlayout import BoxLayout from kivy.uix.gridlayout import GridLayout from kivy.uix.scrollview import ScrollView from kivy.properties import get_color_from_hex from kivy.uix.screenmanager import Screen, ScreenManager from functools import partial connection = sqlite3.connect("recipes.db") cursor = connection.cursor() recipe_get = cursor.execute(""" SELECT id,name FROM recipes ORDER BY name """) class ScreenMan(ScreenManager): def __init__(self, **kwargs): super().__init__(**kwargs) class MainWindow(Screen): def __init__(self, **kwargs): super().__init__(**kwargs) self.name = "acertainmagical" self.add_widget(RecIndex()) class RecIndex(ScrollView): def __init__(self, **kwargs): super().__init__(**kwargs) self.layout = BoxLayout(orientation="vertical",spacing=5,size_hint=(1,None)) self.layout.bind(minimum_height=self.layout.setter("height")) self.add_widget(self.layout) for re in recipe_get: if recipe_get: button = Button(text=re[1], size_hint=(1, None),opacity=1) button.bind(on_release=partial(self.go_to_deets, re[0])) self.layout.add_widget(button) else: self.layout.add_widget( Label(text="No Recipes Found",pos_hint={"center_x":.5,"center_y":.5},size_hint=(.2,.2),opacity=1)) def go_to_deets(self,key,inst): app = App.get_running_app() app.root.transition.direction = "left" app.root.current = "details" app.root.get_screen("details").get_det(key) class SecondWindow(Screen): def __init__(self,**kwargs): super().__init__(**kwargs) self.name = "details" self.layout = BoxLayout(orientation="vertical") self.add_widget(self.layout) def back_to_main(self,inst): app = App.get_running_app() app.root.transition.direction = "right" app.root.current = "acertainmagical" self.layout.clear_widgets() def get_det(self,key): recipe = Recipe() recipe.load_from_db(key) rec_label = Label(text=recipe.name,size_hint=(.15,.2),pos_hint={"center_x":.5,"center_y":.5}) rec_meal = Label(text=recipe.meal_type,size_hint=(.15,.2),pos_hint={"center_x":.5,"center_y":.5}) rec_ingr = TextInput(text=recipe.directions,readonly=True,background_color=get_color_from_hex("#000000"), foreground_color=get_color_from_hex("#F0F0F0"),halign="left") rec_steps = Label(text=recipe.ingredients) back_button = Button(text="Back",size_hint=(1,.2),on_release=partial(self.back_to_main),opacity=1) self.layout.add_widget(rec_label) self.layout.add_widget(rec_meal) self.layout.add_widget(rec_steps) self.layout.add_widget(rec_ingr) self.layout.add_widget(back_button) class KCBApp(App): def build(self): sm = ScreenMan() sm.add_widget(MainWindow()) sm.add_widget(SecondWindow()) return sm if __name__ == "__main__": KCBApp().run()
已尝试方案
- 调整Config配置修改屏幕尺寸
- 使用Window.size修改屏幕尺寸,问题依旧
解决方案
1. 移除固定窗口尺寸配置
Android设备屏幕尺寸多样,固定窗口宽高会和设备实际显示区域(扣除状态栏、导航栏)冲突,导致buffer尺寸不匹配。删除以下代码:
Config.set("graphics","width","700") Config.set("graphics","height","200") Config.write()
如果需要在Windows下保留固定尺寸,添加平台判断:
from kivy.utils import platform from kivy.config import Config if platform == 'win': Config.set("graphics","width","700") Config.set("graphics","height","200") Config.write()
2. 修复ScrollView布局的尺寸设置
RecIndex中的Button没有明确设置height,可能导致布局计算异常,给Button添加固定height:
button = Button(text=re[1], size_hint=(1, None), height=50, opacity=1)
3. 修复数据库路径问题
Android中无法直接访问根目录下的recipes.db,需要适配路径并确保文件被打包到APK:
- 在
buildozer.spec中添加配置,打包数据库文件:
source.include_exts = db,png,jpg,kv,atlas source.include_files = recipes.db
- 修改代码中的数据库连接逻辑:
import sqlite3 import os from kivy.utils import platform if platform == 'android': from android.storage import app_storage_path # 复制assets中的数据库到可写目录(首次启动时执行) src_db = os.path.join(os.environ['APPDIR'], 'assets', 'recipes.db') dest_db = os.path.join(app_storage_path(), 'recipes.db') if not os.path.exists(dest_db): import shutil shutil.copy(src_db, dest_db) connection = sqlite3.connect(dest_db) else: connection = sqlite3.connect("recipes.db")
4. 检查自定义模块兼容性
确保curse.py中的Recipe类没有依赖Windows专属API,并且在Buildozer的requirements中添加了所有必要依赖。
5. 查看完整错误日志
当前Logcat仅显示SurfaceView的buffer问题,可能存在底层Python报错,执行以下命令获取详细日志:
adb logcat | grep Python
内容的提问来源于stack exchange,提问作者kenten25
相关产品推荐
相关产品推荐

