KivyMD应用在Android端root.ids为空崩溃,PC端运行正常求助
问题描述
使用KivyMD开发的GPS应用在PC端Python编译器运行正常,但通过adb安装到Android设备后崩溃。logcat日志显示root.ids为空,无法获取id为home_screen的控件。
相关代码片段
GPSHelper类代码
from kivymd.app import MDApp from kivy.utils import platform from kivymd.uix.dialog import MDDialog class GPSHelper(): has_centered_map = False def run(self): # 获取GpsBlinker引用并调用blink() a = MDApp.get_running_app() print(a) gps_blinker = MDApp.get_running_app().root.ids.home_screen.ids.mapview.ids.blinker # 启动GpsBlinker闪烁 gps_blinker.blink()
logcat报错信息
Traceback (most recent call last): 12-04 14:35:55.595 26138 26205 I python : File "kivy/properties.pyx", line 961, in kivy.properties.ObservableDict.__getattr__ 12-04 14:35:55.595 26138 26205 I python : KeyError: 'home_screen' 12-04 14:35:55.595 26138 26205 I python : 12-04 14:35:55.595 26138 26205 I python : During handling of the above exception, another exception occurred: 12-04 14:35:55.596 26138 26205 I python : 12-04 14:35:55.596 26138 26205 I python : Traceback (most recent call last): 12-04 14:35:55.596 26138 26205 I python : File "/mnt/d/Self/Python-programs/GPS-Copy/.buildozer/android/app/main.py", line 18, in <module> 12-04 14:35:55.596 26138 26205 I python : File "/mnt/d/Self/Python-programs/GPS-Copy/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/FlightGPS/armeabi-v7a/kivy/app.py", line 955, in run 12-04 14:35:55.597 26138 26205 I python : File "/mnt/d/Self/Python-programs/GPS-Copy/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/FlightGPS/armeabi-v7a/kivy/app.py", line 950, in _run_prepare 12-04 14:35:55.597 26138 26205 I python : File "kivy/_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch 12-04 14:35:55.597 26138 26205 I python : File "/mnt/d/Self/Python-programs/GPS-Copy/.buildozer/android/app/main.py", line 16, in on_start 12-04 14:35:55.597 26138 26205 I python : File "/mnt/d/Self/Python-programs/GPS-Copy/.buildozer/android/app/gpshelper.py", line 13, in run 12-04 14:35:55.598 26138 26205 I python : File "kivy/properties.pyx", line 964, in kivy.properties.ObservableDict.__getattr__ 12-04 14:35:55.598 26138 26205 I python : AttributeError: 'super' object has no attribute '__getattr__'. Did you mean: '__setattr__'? 12-04 14:35:55.598 26138 26205 I python : Python for android ended.
kv文件内容
main.kv
#:include homescreen.kv MDScreen: MDNavigationLayout : MDScreenManager : HomeScreen: id: home_screen
homescreen.kv
#:import utils kivy.utils #:include homemapview.kv <HomeScreen>: MDBoxLayout: orientation: 'vertical' # 信息栏 MDBoxLayout: orientation: 'horizontal' padding: '10dp' adaptive_height: True # size_hint: {.6, .1} MDLabel: text: 'Speed(km/hr) : ' halign: 'left' valign: 'top' font_size: 20 MDLabel: text: 'Location' halign: 'right' valign: 'top' font_size: 20 FloatLayout: # 地图区域 HomeMapView: id: mapview # 按钮栏 MDBoxLayout: padding: '5dp' adaptive_height: True MDIconButton: icon: 'crosshairs-gps'
排查与解决方案
核心原因
Android端界面加载速度远慢于PC端,在on_start阶段调用GPSHelper.run()时,kv文件中的控件还未完成初始化,导致root.ids尚未填充home_screen对象。
具体解决办法
延迟执行控件获取逻辑
使用Kivy的Clock.schedule_once延迟调用run方法,给界面足够的初始化时间:from kivy.clock import Clock # 在App类的on_start方法中修改调用逻辑 def on_start(self): Clock.schedule_once(lambda dt: GPSHelper().run(), 1) # 延迟1秒执行,可根据实际调整时长修正控件层级访问路径
home_screen是MDScreenManager的子控件,需先获取MDScreenManager再访问其ids。先给MDScreenManager添加id:#:include homescreen.kv MDScreen: MDNavigationLayout : MDScreenManager : id: screen_manager HomeScreen: id: home_screen然后调整代码中的访问路径:
gps_blinker = MDApp.get_running_app().root.ids.screen_manager.ids.home_screen.ids.mapview.ids.blinker确保kv文件与Python类匹配
- 确认
HomeScreen类在Python代码中正确继承自MDScreen,否则kv文件中的规则无法生效:from kivymd.uix.screen import MDScreen class HomeScreen(MDScreen): pass - 检查buildozer.spec配置,确保所有kv文件都被包含在打包资源中,避免遗漏。
- 确认
添加异常处理避免崩溃
深层链式访问ids容易因某一层未初始化报错,建议分步获取并添加异常捕获:def run(self): app = MDApp.get_running_app() try: root = app.root screen_manager = root.ids.screen_manager home_screen = screen_manager.ids.home_screen mapview = home_screen.ids.mapview gps_blinker = mapview.ids.blinker gps_blinker.blink() except AttributeError as e: print(f"控件获取失败: {e}") # 可添加重试逻辑或弹窗提示用户
内容的提问来源于stack exchange,提问作者Rishabh
相关产品推荐
相关产品推荐

