Android应用访问XAMPP本地数据库时JSONObject为空致崩溃原因排查
排查Android应用访问本地XAMPP数据库时JSONObject为空的问题
我来帮你一步步分析这个导致崩溃的空指针问题,咱们从最常见的原因开始排查:
一、先确认网络与服务器基础连通性
这是最容易忽略的前提:
- 检查设备与服务器的局域网一致性:确保你的Android设备和运行XAMPP的电脑在同一个WiFi网络下,并且
BASE_URL里的192.168.0.169是电脑的正确局域网IP(可以在电脑的命令行用ipconfig(Windows)或ifconfig(Linux/Mac)查看)。 - 直接用手机浏览器测试接口:打开手机浏览器,访问
http://192.168.0.169/movies/fetch_all_movies.php。如果浏览器打不开或者返回错误页面,那问题出在XAMPP配置或PHP脚本,和App代码无关:- 确认XAMPP的Apache服务已经启动;
- 确认
fetch_all_movies.php文件放在XAMPP的htdocs/movies/目录下; - 检查PHP脚本是否有语法错误或数据库连接失败,可以在PHP开头添加错误输出:
error_reporting(E_ALL); ini_set('display_errors', 1); - 确保PHP脚本返回的是合法JSON格式,比如正确的结构应该是:
{"success":1,"data":[{"movie_id":"1","movie_name":"Test Movie"}]}
二、检查Android应用的网络权限与明文访问限制
- 添加网络权限:在
AndroidManifest.xml中必须声明网络权限:<uses-permission android:name="android.permission.INTERNET" /> - Android 9+明文HTTP访问限制:如果你的App目标SDK是28及以上,默认禁止明文HTTP请求,需要在
AndroidManifest.xml的application标签中添加:android:usesCleartextTraffic="true"
三、修复HttpJsonParser类的错误处理缺陷
你的HttpJsonParser类在出现网络错误、服务器错误或JSON解析失败时,只是打印日志但依然返回null,导致后续代码崩溃。我们需要增强错误处理,明确问题原因:
public JSONObject makeHttpRequest(String url, String method, Map<String, String> params) { try { Uri.Builder builder = new Uri.Builder(); URL urlObj; String encodedParams = ""; if (params != null) { for (Map.Entry<String, String> entry : params.entrySet()) { builder.appendQueryParameter(entry.getKey(), entry.getValue()); } } if (builder.build().getEncodedQuery() != null) { encodedParams = builder.build().getEncodedQuery(); } if ("GET".equals(method)) { url = url + "?" + encodedParams; urlObj = new URL(url); urlConnection = (HttpURLConnection) urlObj.openConnection(); urlConnection.setRequestMethod(method); } else { urlObj = new URL(url); urlConnection = (HttpURLConnection) urlObj.openConnection(); urlConnection.setRequestMethod(method); urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); urlConnection.setRequestProperty("Content-Length", String.valueOf(encodedParams.getBytes().length)); urlConnection.getOutputStream().write(encodedParams.getBytes()); } urlConnection.connect(); // 新增:检查服务器响应码 int responseCode = urlConnection.getResponseCode(); if (responseCode != HttpURLConnection.HTTP_OK) { // 读取错误流,打印错误信息 is = urlConnection.getErrorStream(); BufferedReader errorReader = new BufferedReader(new InputStreamReader(is)); StringBuilder errorSb = new StringBuilder(); String errorLine; while ((errorLine = errorReader.readLine()) != null) { errorSb.append(errorLine + "\n"); } Log.e("HttpError", "Response Code: " + responseCode + ", Error Message: " + errorSb.toString()); is.close(); return null; } is = urlConnection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); StringBuilder sb = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } is.close(); json = sb.toString(); Log.d("ReceivedJson", json); // 新增:打印收到的原始JSON,方便排查格式问题 jObj = new JSONObject(json); } catch (UnsupportedEncodingException e) { Log.e("EncodingError", e.toString()); } catch (ProtocolException e) { Log.e("ProtocolError", e.toString()); } catch (IOException e) { Log.e("IOException", e.toString()); } catch (JSONException e) { Log.e("JSONParserError", "Failed to parse JSON: " + e.toString() + ", Raw JSON: " + json); } catch (Exception e) { Log.e("GeneralError", e.toString()); } finally { if (urlConnection != null) { urlConnection.disconnect(); // 新增:关闭连接,避免资源泄漏 } } return jObj; }
四、在MovieListingActivity中添加空指针判断
在doInBackground中,必须先判断jsonObject是否为null,再进行后续操作,避免崩溃:
@Override protected String doInBackground(String... params) { HttpJsonParser httpJsonParser = new HttpJsonParser(); JSONObject jsonObject = httpJsonParser.makeHttpRequest( BASE_URL + "fetch_all_movies.php", "GET", null); if (jsonObject != null) { try { int success = jsonObject.getInt(KEY_SUCCESS); // 这里可以继续处理成功后的逻辑,比如解析data数组 Log.d("Success", "Success code: " + success); } catch (JSONException e) { Log.e("JSONError", "Failed to get success key: " + e.getMessage()); e.printStackTrace(); } } else { Log.e("NullError", "JSONObject is null - check network, server or PHP script"); } return null; }
按照这个顺序排查,你应该能快速定位到问题所在——大概率是网络连通性、PHP脚本错误或者Android的明文访问限制导致的。
内容的提问来源于stack exchange,提问作者HCS KUL
相关产品推荐
相关产品推荐

