You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

安卓模拟器直连MySQL报SQLNonTransientConnectionException连接异常

问题核心根因

从堆栈日志可直接定位两个和「独立测试能跑通、但模拟器运行崩溃」完全对应的原因:

  • 最直接的崩溃触发点:NetworkOnMainThreadException。安卓系统从4.0版本开始,强制禁止在主线程(负责UI渲染、交互响应的线程)执行任何网络操作,包括JDBC数据库连接。你当前的代码是在SearchFragment.onCreateView的主线程逻辑里直接调用DriverManager.getConnection,被系统直接拦截抛出异常,最终上层包装成数据库连接失败的报错。你之前的独立测试是纯JVM环境运行,没有安卓的主线程网络限制规则,所以不会触发崩溃。
  • 容易被忽略的地址配置错误:你当前JDBC连接地址用的是localhost:3306,在安卓模拟器环境中,这个地址指向的是模拟器自身的内部回环地址,不是你开发电脑上运行的MySQL服务。就算解决了主线程的限制,用这个地址也无法连通宿主机的数据库。安卓模拟器预留了固定IP 10.0.2.2,专门用来访问宿主机(开发电脑)上运行的网络服务。
可直接落地的修复步骤
  • 将数据库连接、查询操作移出主线程
    不要在Fragment/Activity的生命周期回调里同步执行数据库逻辑,用协程切到IO线程执行即可,示例写法:
    // 在Fragment的onCreateView中调用,通过viewScope启动协程
    viewScope.launch(Dispatchers.IO) {
        val queryResult = getData()
        // 拿到查询结果后切回主线程,更新UI控件
        withContext(Dispatchers.Main) {
            // 绑定结果到视图的逻辑
        }
    }
    
  • 修改JDBC连接的主机地址
    把原url里的localhost替换成10.0.2.2,调整后的连接地址写法:
    val url = "jdbc:mysql://10.0.2.2:3306/Stonks?verifyServerCertificate=false&useSSL=false&autoReconnect=true"
    
  • 完成前置环境校验,避免后续连不通:
    • 确认项目的AndroidManifest.xml中已添加网络权限:<uses-permission android:name="android.permission.INTERNET" />
    • 确认MySQL给Shane用户开放了跨IP访问权限,不要只允许localhost来源的连接
    • 确认开发电脑的防火墙没有拦截3306端口的入站请求

内容的提问来源于stack exchange,提问作者Shane Claycomb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.26 21:15:02