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

Android Studio(Java)连接Azure MySQL数据库失败求助

解决Android连接Azure MySQL时的NetworkOnMainThreadException异常

核心问题原因

android.os.NetworkOnMainThreadException是Android系统的强制限制——主线程不能执行网络操作,目的是避免UI卡顿。你当前的JDBC连接代码应该是直接写在Activity/Fragment的主线程里了,这是根本问题,和JDBC版本、IP正确性无关。

解决方案:将数据库操作移至后台线程

下面提供几种适合学校项目的实现方式:

方式1:使用Kotlin协程(推荐,现代Android开发首选)

如果你的项目用Kotlin,直接用协程将数据库操作切换到IO线程:

// 在Activity或Fragment中
lifecycleScope.launch(Dispatchers.IO) {
    try {
        // 这里执行JDBC连接和数据库操作
        val connection = DriverManager.getConnection(
            "jdbc:mysql://<你的Azure MySQL地址>:3306/<数据库名>?useSSL=true&requireSSL=false",
            "<用户名>",
            "<密码>"
        )
        // 执行SQL操作,比如创建用户
        val stmt = connection.prepareStatement("INSERT INTO users (name, email) VALUES (?, ?)")
        stmt.setString(1, "testUser")
        stmt.setString(2, "test@example.com")
        stmt.executeUpdate()
        
        // 操作完成后切回主线程更新UI
        withContext(Dispatchers.Main) {
            Toast.makeText(this@YourActivity, "用户创建成功", Toast.LENGTH_SHORT).show()
        }
        // 关闭资源
        stmt.close()
        connection.close()
    } catch (e: Exception) {
        e.printStackTrace()
        withContext(Dispatchers.Main) {
            Toast.makeText(this@YourActivity, "连接失败:${e.message}", Toast.LENGTH_SHORT).show()
        }
    }
}

方式2:使用AsyncTask(兼容旧版本,已过时但学校项目仍可使用)

如果是Java项目,用AsyncTask封装后台操作:

public class DBTask extends AsyncTask<Void, Void, Boolean> {
    private Context context;
    private String userName;
    private String userEmail;

    public DBTask(Context context, String userName, String userEmail) {
        this.context = context;
        this.userName = userName;
        this.userEmail = userEmail;
    }

    @Override
    protected Boolean doInBackground(Void... voids) {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection connection = DriverManager.getConnection(
                "jdbc:mysql://<你的Azure MySQL地址>:3306/<数据库名>?useSSL=true&requireSSL=false",
                "<用户名>",
                "<密码>"
            );
            PreparedStatement stmt = connection.prepareStatement("INSERT INTO users (name, email) VALUES (?, ?)");
            stmt.setString(1, userName);
            stmt.setString(2, userEmail);
            stmt.executeUpdate();
            
            stmt.close();
            connection.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    protected void onPostExecute(Boolean success) {
        super.onPostExecute(success);
        if (success) {
            Toast.makeText(context, "用户创建成功", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(context, "操作失败", Toast.LENGTH_SHORT).show();
        }
    }
}

// 在Activity中调用
new DBTask(this, "testUser", "test@example.com").execute();

方式3:使用普通Thread+Handler

// 在Activity中
new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            // JDBC连接和操作代码
            Connection connection = DriverManager.getConnection(...);
            // ...执行SQL
            connection.close();
            
            // 通知主线程更新UI
            handler.post(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(YourActivity.this, "操作成功", Toast.LENGTH_SHORT).show();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
            handler.post(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(YourActivity.this, "失败:"+e.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
}).start();

// 定义Handler
private Handler handler = new Handler(Looper.getMainLooper());

额外注意事项

  • 网络权限:确保Manifest中已添加权限:
<uses-permission android:name="android.permission.INTERNET" />
  • Azure MySQL配置:
    • 确认Azure门户中已将你的设备IP添加到MySQL服务器的防火墙规则(你说Workbench能连,这步应该没问题,但再核对下)
    • JDBC URL需包含SSL参数:useSSL=true&requireSSL=false(Azure MySQL默认要求SSL,不添加会连接失败)
  • JDBC依赖:在build.gradle中使用正确的依赖,比如:
dependencies {
    implementation 'mysql:mysql-connector-java:8.0.33'
    // Kotlin项目可替换为 implementation 'com.mysql:mysql-connector-j:8.0.33'
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 12:23:10