Android Studio使用jTDS连接SQL Server时createStatement空指针异常问题
问题根因
java.lang.NullPointerException的直接触发原因是Connection对象为null:DriverManager.getConnection()执行过程中抛出异常,导致connection变量没有被赋值,保持初始默认值null,后续调用connection.createStatement()时触发空对象引用异常。
数据库连接失败的常见原因如下:
- SQL Server默认禁用TCP/IP连接协议,仅开启命名管道访问,无法通过IP+端口的方式远程连接
- Windows系统防火墙拦截了SQL Server默认使用的1433端口,外部设备无法访问该端口
- 两台设备网络不通:MacBook和部署SQL Server的Windows PC不在同一局域网,或者填写的Windows IPv4地址有误
- 连接URL配置错误:如果SQL Server使用命名实例,未在URL中补充实例名参数,或者参数格式不符合jtds驱动要求
- 账号权限不足:创建的
android用户未开启远程登录权限,或者没有dbExemplu数据库的访问、写入权限
解决方案
一、SQL Server与网络配置排查
- 启用TCP/IP协议
打开SQL Server配置管理器,进入「SQL Server网络配置」-「对应实例的协议」,右键点击「TCP/IP」选择启用;切换到「IP地址」标签页,拉到最下方「IPAll」分组,将TCP端口设置为1433,确认后重启SQL Server服务生效。 - 放行1433端口
可以临时关闭Windows防火墙测试连接是否正常,确认是防火墙问题后,在防火墙高级设置中添加入站规则,允许1433端口的TCP连接。 - 测试网络连通性
在MacBook终端执行telnet <Windows端IPv4地址> 1433,如果无法连通,先排查局域网连通性,确认两台设备在同一网段、IP地址填写正确。 - 修正连接URL
如果SQL Server是命名实例(默认安装的Express版默认是命名实例SQLEXPRESS),需要在URL中补充实例名参数,示例:
String sirUrl = "jdbc:jtds:sqlserver://" + ip + ":" + port + ";databasename=" + database + ";instance=SQLEXPRESS;user=" + user + ";password=" + password + ";useSSL=false;";
- 验证账号权限
使用SSMS工具,以android用户名密码登录SQL Server,确认可以正常访问dbExemplu数据库,且拥有Furnizori表的写入权限。
二、代码优化
- 新增空判断逻辑,避免空指针
在调用createStatement()前先判断connection是否为null:
void addVendor(String code, String name, String phone) { if (connection == null) { Log.e("Error", "数据库连接未初始化成功"); return; } // 后续业务逻辑 }
- 修复现有代码语法错误
将vendor.getPhone().toString修正为vendor.getPhone().toString(),如果vendor(txtCode.getText().toString())是设置code的逻辑,确认对应的set方法调用格式正确。 - 避免SQL注入风险
不要直接拼接SQL语句,改用PreparedStatement预处理语句:
String s = "insert into Furnizori values (?,?,?)"; PreparedStatement pst = connection.prepareStatement(s); pst.setString(1, code); pst.setString(2, name); pst.setString(3, phone); pst.executeUpdate();
- 优化线程逻辑
StrictMode.ThreadPolicy.Builder().permitAll().build()仅可作为开发阶段临时绕过方案,生产环境需将数据库IO操作放到子线程执行,可使用Coroutine或者AsyncTask实现。
内容的提问来源于stack exchange,提问作者Catalin Petraru
相关产品推荐
相关产品推荐

