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
相关产品推荐
相关产品推荐

