Android应用连接MySQL Docker容器失败报错问题求助
问题排查与解决步骤
1. 主线程网络操作错误
你的错误栈明确抛出了android.os.NetworkOnMainThreadException,Android系统从3.0版本开始就禁止在主线程执行网络请求、数据库连接这类耗时操作,你当前的连接逻辑直接写在onCreate生命周期方法中,属于主线程执行场景,会被系统直接拦截报错。
解决方法:将数据库相关操作放到子线程中执行,入门阶段可以直接使用Thread类实现,后续熟悉后可以替换为协程、线程池等更规范的实现。
2. 数据库连接地址错误
你当前配置的连接地址是jdbc:mysql://localhost:3306/appDB,这里的localhost指向的是运行应用的Android模拟器/真机本身,而非你电脑上运行的Docker MySQL容器,自然无法找到对应的数据库服务。
解决方法:
- 如果使用Android官方模拟器,将地址替换为
10.0.2.2,这是模拟器预留的指向宿主电脑的特殊IP - 如果使用真机测试,确保手机和电脑连接同一个WiFi,将地址替换为电脑的局域网IP
- 额外确认Docker MySQL容器已经将3306端口映射到宿主机的3306端口,且电脑防火墙放开了3306端口的访问权限
3. 必要配置检查
- 必须在
AndroidManifest.xml中添加网络权限,否则也会触发连接失败:<uses-permission android:name="android.permission.INTERNET" /> - 启动Docker MySQL容器时需要配置
MYSQL_ROOT_HOST=%参数,否则root用户默认只允许本地登录,就算网络连通也会被MySQL拒绝访问 - MySQL 8.0版本连接时建议在url后追加
allowPublicKeyRetrieval=true&useSSL=false参数,避免加密校验、公钥获取类的额外报错
修改后可运行的参考代码
package com.example.databaseapp; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import java.sql.Connection; import java.sql.DriverManager; public class MainActivity extends AppCompatActivity { // 模拟器用10.0.2.2,真机同WiFi测试填电脑局域网IP private static final String url = "jdbc:mysql://10.0.2.2:3306/appDB?allowPublicKeyRetrieval=true&useSSL=false"; private static final String user = "root"; private static final String pass = "my-sec"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 所有数据库操作放到子线程执行 new Thread(() -> { try { Class.forName("com.mysql.cj.jdbc.Driver").newInstance(); System.out.println("Driver register success!"); Connection con = DriverManager.getConnection(url, user, pass); System.out.println("Database connection success!"); } catch (Exception e){ System.out.println("Database operation failure..."); e.printStackTrace(); } }).start(); } }
内容的提问来源于stack exchange,提问作者Katelyn
相关产品推荐
相关产品推荐

