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

Android Studio JDBC连接本地MySQL报连接失败异常解决方案

Android模拟器连接本地MySQL失败修复方案

问题现象

开发环境为Android Studio,尝试连接PC本地MySQL数据库时抛出如下错误:

W/System.err: java.sql.SQLNonTransientConnectionException: Could not create connection to database server.

初始JDBC连接代码如下:

conn = DriverManager.getConnection("jdbc:mysql://10.0.2.2:3306/gimnasio","root","");

其中10.0.2.2为Android官方模拟器映射的PC本地回环地址,配置后始终连接失败。尝试改用PHP WebService中转方案时,自定义URL常量配置如下,仍无法正常调用:

public class URLs {
        public static final String ROOT_URL = "http://webservice.local/index.php";
        public static final String USER = "root";
        public static final String PASSWORD = "";
}

登录逻辑通过按钮点击触发,相关代码如下:

// set on-click listener
btnLogin.setOnClickListener {
    login(user_mail_text, user_password_text)
}

private fun login(email:String, password:String) {
    UserDao().login(email, password)
}

UserDao类核心代码:

public boolean login(String email, String password) throws IOException {
    String sql = "select * from users where email = ? and password = ?";
    Connection con = JDBCUtils.getConn();
    try {

JDBCUtils类核心代码:

public static Connection getConn() {
    Connection  conn = null;
    try {
        conn = DriverManager.getConnection("jdbc:mysql://10.0.2.2:3306/gimnasio","root","");
    }catch (Exception exception){
        exception.printStackTrace();
    }
    return conn;
}

核心问题原因

  • 移动端不推荐直接JDBC直连MySQL:该方案需要将数据库账号密码硬编码到APK中,反编译即可直接获取,存在严重安全风险,仅适合本地临时调试。
  • 主线程执行网络操作违规:Android 3.0及以上版本禁止在UI主线程发起任何网络请求,直接在点击回调里执行数据库连接/HTTP请求会被系统拦截。
  • 基础配置缺失:包括网络权限未声明、MySQL未开放远程访问、防火墙拦截端口、JDBC驱动与MySQL版本不匹配、连接串缺少必要参数、明文HTTP请求被系统拦截、自定义域名无hosts映射等。

可行解决步骤

优先选择WebService中转方案,不要在生产环境使用JDBC直连。

方案1:临时调试用JDBC直连修复

  • 声明网络权限:在AndroidManifest.xml中<application>标签的同级位置添加权限:
    <uses-permission android:name="android.permission.INTERNET" />
    
  • 配置MySQL远程访问权限:本地登录MySQL执行如下命令,创建允许远程访问的业务账号(不要直接用root账号开启远程访问):
    -- MySQL 8.0+版本适用
    CREATE USER 'appdebug'@'%' IDENTIFIED BY '自定义调试密码';
    GRANT ALL PRIVILEGES ON gimnasio.* TO 'appdebug'@'%';
    FLUSH PRIVILEGES;
    
    临时关闭PC本地防火墙,或配置防火墙放行3306端口的入站连接。
  • 匹配JDBC驱动版本:在模块级build.gradle的dependencies节点添加和本地MySQL版本一致的驱动依赖,比如本地装MySQL 8.0.x就引入对应版本:
    implementation 'mysql:mysql-connector-java:8.0.33'
    
  • 修正JDBC连接串:MySQL 8.0+版本需要补充时区、SSL、公钥检索参数:
    // 8.0+版本驱动类为com.mysql.cj.jdbc.Driver,不要用旧的com.mysql.jdbc.Driver
    conn = DriverManager.getConnection("jdbc:mysql://10.0.2.2:3306/gimnasio?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true","appdebug","自定义调试密码");
    
  • 将所有数据库操作切到子线程执行,操作完成后再切回主线程更新UI,Kotlin中可以直接用内置thread方法:
    private fun login(email:String, password:String) {
        thread {
            val loginResult = UserDao().login(email, password)
            runOnUiThread {
                // 处理登录结果,比如页面跳转、提示弹窗
            }
        }
    }
    

方案2:PHP WebService中转方案修复(推荐)

  • 先在PC本地验证PHP服务可用性:确保PC浏览器访问http://127.0.0.1/index.php可以正常返回预期内容,修正URL常量,不要用无映射的自定义.local域名,直接用模拟器可访问的PC地址:
    public class URLs {
        public static final String ROOT_URL = "http://10.0.2.2/index.php";
        // 不要把数据库账号密码写在移动端代码里,数据库连接逻辑全部放到PHP脚本中处理
    }
    
  • 解决Android 9+ 明文HTTP请求拦截问题:在AndroidManifest.xml的<application>标签添加如下属性:
    <application
        android:usesCleartextTraffic="true"
        <!-- 保留原有其他属性不变 -->
    >
    
  • 所有HTTP接口请求同样需要放到子线程执行,推荐用OkHttp、Retrofit等成熟网络框架发起请求,移动端仅负责传入邮箱、密码参数,接收PHP接口返回的登录结果即可,数据库的账号密码仅保存在PHP服务端,不会泄露。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 21:54:20