Android真机无法连接微软Azure托管SQL数据库 模拟器运行正常
问题根因
你遇到的SSL握手中断错误是TLS版本协商失败导致的:Azure SQL服务默认仅支持TLS 1.2及以上版本加密连接,你使用的jTDS驱动默认没有强制指定TLS 1.2版本,Android 10真机的系统SSL上下文配置和API 31模拟器存在差异,握手时双方无法协商到一致的加密协议版本,连接被服务端主动断开才会报Broken pipe错误。
修复步骤
- 修改JDBC连接URL,强制指定TLS版本
在你现有的连接URL末尾追加;sslProtocol=TLSv1.2参数即可,修改后的URL参考:
jdbc:jtds:sqlserver://moons.database.windows.net:1433;DatabaseName=****;user=****;password=****;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;ssl=request;sslProtocol=TLSv1.2
90%以上的同类问题修改完这个参数就可以正常连接。
替换老旧的jTDS驱动
jTDS驱动已经停止更新多年,对新的加密协议、Azure SQL服务的适配性很差,如果修改URL参数后仍然报错,建议替换为微软官方维护的mssql-jdbc驱动,选择适配JDK 8的版本即可完美兼容你的minSDK 25配置,连接语法基本和jTDS一致,不需要大幅修改现有代码。排查网络层面拦截
确认华为真机当前连接的网络(WiFi/移动数据)没有封禁1433端口的出站连接,部分运营商网络或者公司内网会拦截SQL Server默认的1433端口,你可以在真机上安装端口扫描工具测试moons.database.windows.net的1433端口连通性,排除网络拦截问题。补充网络安全配置
在res/xml目录下新建network_security_config.xml文件,添加如下配置放行Azure SQL域名的加密连接:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">database.windows.net</domain> </domain-config> </network-security-config>
之后在AndroidManifest.xml的application标签中添加属性android:networkSecurityConfig="@xml/network_security_config"即可。
额外优化建议
从日志中能看到主线程跳帧警告,你当前把数据库连接这类耗时网络操作放在主线程执行,会导致界面卡顿、甚至触发ANR异常,Android要求所有网络操作必须放在子线程执行,建议用协程(Coroutine)或者工作线程把数据库连接逻辑移到后台执行。
内容的提问来源于stack exchange,提问作者MoonLight

