Kivy开发APK连接PC本地MySQL崩溃及黑屏问题求助
问题描述
我用Kivy+Python3开发了一款应用,完成界面设计后对接了MySQL数据库实现数据收发。打包成APK在Android设备测试时,界面能正常运行,但只要触发数据库交互就崩溃,加了Try-Except语句也没用。我怀疑Android与PC本地数据库的连接环节存在问题,以下是相关信息:
连接代码
class FifthScreen(Screen): users = os.environ.get('USER_NAME') pass_word = os.environ.get('WORDPASS') try: database = mysql.connector.connect(host="localhost", user=users, password=pass_word, database="logintest", port= "3306") cursor = database.cursor() except Error as e: print(e) admin_email = "rasheed@hotmail.com" admin_password = "King" loggedin = False def receive_data(self, email, password): try: self.cursor.execute("select email,password from logs") email_list = [] for i in self.cursor.fetchall(): email_list.append(i[0]) if email.text in email_list and email.text != "": self.cursor.execute(f"select password,user_name from logs where email='{email.text}'") for j in self.cursor: if email.text == self.admin_email and password.text == self.admin_password: print("Hello Admin") self.manager.current = 'Data_Table' elif password.text == j[0]: print("you successfully logged in") self.manager.current = 'Doctors_Patients_Details' self.loggedin = True self.manager.get_screen('photo_page').ids.user_name.text = j[1] else: print("incorrect password ") else: print("incorrect email") except Error as e: print(e) finally: if self.database.is_connected(): self.database.close() self.cursor.close() print("closed4")
Buildozer依赖配置
requirements = python3,kivy==2.1.0,kivymd==0.104.2,pillow, requests,android,docutils,mysql_connector,mysql-connector-python,fpdf android.permissions = INTERNET,READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE
修改后的问题(将host改为PC IP192.168.43.64,开放3306端口并关闭防火墙后)
- 数据库交互仍崩溃,报错信息:
Traceback (most recent call last): 10-25 21:19:50.841 3641 4045 I python : File "/content/.buildozer/android/app/main.py", line 328, in receive_data 10-25 21:19:50.843 3641 4045 I python : AttributeError: 'FifthScreen' object has no attribute 'cursor' AttributeError: 'FifthScreen' object has no attribute 'database' 10-25 21:19:50.848 3641 4045 I python : Python for android ended.
- 闪屏后黑屏持续3-4分钟,日志信息:
win=Window{3e4abc u0 Splash Screen org.test.test3 EXITING} destroySurfaces: appStopped=false win.mWindowRemovalAllowed=true win.mRemoveOnExit=true
解决方案
1. 修复类属性初始化问题
报错'FifthScreen' object has no attribute 'cursor'的核心原因:你在类定义外层直接写了数据库连接的try-except块,这里创建的database和cursor是类变量,如果连接失败(比如Android初始化时网络未就绪),这两个变量不会被赋值,后续实例调用self.cursor时就会找不到属性。另外,类初始化阶段就尝试数据库连接不合理,应该在需要的时候(比如receive_data方法内)才建立连接。
修改后的代码:
class FifthScreen(Screen): admin_email = "rasheed@hotmail.com" admin_password = "King" loggedin = False def receive_data(self, email, password): database = None cursor = None try: # 按需获取凭据 users = os.environ.get('USER_NAME') pass_word = os.environ.get('WORDPASS') # 方法内建立连接,避免初始化阻塞 database = mysql.connector.connect( host="192.168.43.64", user=users, password=pass_word, database="logintest", port="3306" ) cursor = database.cursor() cursor.execute("select email,password from logs") # 简化列表生成 email_list = [i[0] for i in cursor.fetchall()] input_email = email.text.strip() if input_email in email_list: # 使用参数化查询,避免SQL注入 cursor.execute( "select password,user_name from logs where email=%s", (input_email,) ) result = cursor.fetchone() if result: db_password, user_name = result input_pwd = password.text.strip() if input_email == self.admin_email and input_pwd == self.admin_password: print("Hello Admin") self.manager.current = 'Data_Table' elif input_pwd == db_password: print("you successfully logged in") self.manager.current = 'Doctors_Patients_Details' self.loggedin = True self.manager.get_screen('photo_page').ids.user_name.text = user_name else: print("incorrect password ") else: print("incorrect email") else: print("incorrect email") except Error as e: print(f"数据库错误: {e}") finally: # 确保资源正常关闭,避免空指针 if cursor: cursor.close() if database and database.is_connected(): database.close() print("closed4")
2. 解决Android与PC本地MySQL的连接问题
- 确认网络互通:Android设备必须和PC在同一局域网,可通过ADB shell执行
ping 192.168.43.64测试连通性。 - MySQL权限配置:默认MySQL用户仅允许本地访问,需创建支持局域网访问的用户:
注:CREATE USER '你的用户名'@'%' IDENTIFIED BY '你的密码'; GRANT ALL PRIVILEGES ON logintest.* TO '你的用户名'@'%'; FLUSH PRIVILEGES;%允许所有IP访问,测试完成后可改为Android设备的固定IP提升安全性。 - 修改MySQL配置:打开
my.cnf或my.ini,将bind-address改为0.0.0.0(允许所有IP访问),然后重启MySQL服务。
3. 解决闪屏后黑屏问题
黑屏是因为类初始化阶段就尝试数据库连接,阻塞了UI线程。将连接逻辑移到receive_data方法内后,启动时不会再阻塞UI。此外还可以:
- 在Buildozer配置中指定合适的API级别:
android.api = 30 - 优化闪屏配置:
android.splash_drawable = res/drawable/splash.png android.splash_screen_duration = 2000
4. 额外安全建议
- 禁止用字符串拼接SQL语句,改用参数化查询(如上述代码所示),避免SQL注入风险。
- 不要硬编码数据库凭据,通过环境变量或安全配置方式传递。
- 建议搭建HTTPS接口作为中间层,Android调用API间接操作数据库,直接连接MySQL存在安全隐患。
内容的提问来源于stack exchange,提问作者Abdallah Rasheed
相关产品推荐
相关产品推荐

