Android MySQL Volley注册模块触发NullPointerException求助
从你的报错日志和代码来看,这个空指针异常的根源很明确:Volley在编码请求参数时,遇到了null值的字符串,导致URLEncoder.encode调用length()方法时崩溃。下面一步步帮你定位和解决问题:
1. 报错根源分析
日志里的栈追踪显示:
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference at java.net.URLEncoder.encode(URLEncoder.java:205)
这说明你通过getParams()传给Volley的参数中,存在null值。看你的Java代码,registerUser的所有参数都是从SharedPreferences获取的,比如:
final String userName = preferences.getString("Name", null);
如果SharedPreferences中没有对应key的值,就会返回null,这些null值被放到请求参数里,Volley编码时就会触发异常。
另外,你的PHP代码里还有一个潜在问题:你接收了$_POST['txtname'],但Java代码的请求参数里并没有传这个键(Java里传的是fname),这会导致PHP端$uname为null,后续插入数据库也会出错。
2. 分步解决方案
方案一:提前校验参数,避免null进入请求
在调用registerUser之前,先检查所有参数是否为空,确保用户填完了所有信息:
btn_signup.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { final String userName = preferences.getString("Name", null); final String userEmail = preferences.getString("Email", null); final String userPassword = preferences.getString("Password", null); final String userMobile = preferences.getString("Mobile", null); final String userCity = preferences1.getString("City", null); final String userDob = preferences1.getString("Dob", null); final String userTax = preferences1.getString("Tax", null); final String userCnic = preferences1.getString("Cnic", null); final String userBusiness = preferences2.getString("Business", null); final String userNtn = preferences2.getString("Ntn", null); // 检查所有必填参数是否为空(同时处理null和空字符串) if (TextUtils.isEmpty(userName) || TextUtils.isEmpty(userEmail) || TextUtils.isEmpty(userPassword) || TextUtils.isEmpty(userMobile) || TextUtils.isEmpty(userCity) || TextUtils.isEmpty(userDob) || TextUtils.isEmpty(userTax) || TextUtils.isEmpty(userCnic) || TextUtils.isEmpty(userBusiness) || TextUtils.isEmpty(userNtn)) { Toast.makeText(getApplicationContext(), "请完善所有注册信息后再提交", Toast.LENGTH_LONG).show(); return; // 参数不全,不发起请求 } registerUser(userName,userEmail,userPassword,userMobile,userCity,userDob,userTax,userCnic,userBusiness,userNtn); } });
方案二:给SharedPreferences设置默认空字符串,杜绝null
把getString的默认值从null改为空字符串,这样即使没有对应值,也不会返回null:
final String userName = preferences.getString("Name", ""); final String userEmail = preferences.getString("Email", ""); final String userPassword = preferences.getString("Password", ""); final String userMobile = preferences.getString("Mobile", ""); final String userCity = preferences1.getString("City", ""); final String userDob = preferences1.getString("Dob", ""); final String userTax = preferences1.getString("Tax", ""); final String userCnic = preferences1.getString("Cnic", ""); final String userBusiness = preferences2.getString("Business", ""); final String userNtn = preferences2.getString("Ntn", "");
这个方案可以作为方案一的补充,双重保障避免null进入请求参数。
方案三:修正PHP端的参数接收问题
你的PHP代码里有一行:
$uname = mysqli_real_escape_string( $conn,$_POST['txtname'] );
但Java代码的请求参数里并没有txtname这个键,而是传的fname。你需要二选一修正:
- 要么把PHP里的
$_POST['txtname']改成$_POST['fname']; - 要么在Java的
getParams()里添加一行params.put("txtname", userName);。
否则PHP端的$uname会是null,导致后续插入数据库失败。
3. 调试小技巧
在getParams()方法里打印所有参数,方便快速排查哪个参数是null:
@Override protected Map<String, String> getParams() { Map<String, String> params = new HashMap<String, String>(); params.put("txtemail", userEmail); params.put("fname", userName); params.put("city", userCity); params.put("txtpassword", userPassword); params.put("mphone", userMobile); params.put("ntn", userNtn); params.put("cnic", userCnic); params.put("bname", userBusiness); params.put("tpay", userTax); params.put("dob", userDob); // 打印参数到Logcat,方便调试 Log.d(TAG, "请求参数:" + params.toString()); return params; }
另外,建议暂时开启PHP的错误日志,把error_reporting(0);改成error_reporting(E_ALL);,这样如果后端有参数缺失或数据库错误,能直接看到报错信息,方便调试。
内容的提问来源于stack exchange,提问作者Areeba Shaikh

