安卓App读取MySQL数据触发NullPointerException问题求助
解决安卓App加载JSON数据时的NullPointerException问题
从你的日志和代码来看,这个NullPointerException的核心原因是传给JSONArray构造方法的参数是null,而这个null来自AsyncTask的doInBackground方法——说明你的网络请求过程中抛出了异常,导致返回了null,最终在loadIntoListView里解析JSON时触发了错误。
下面是一步步的排查和修复方案:
一、先解决最常见的网络请求基础问题
1. 修正模拟器访问本地服务器的地址
你代码里用的是http://127.0.0.1/api/stock_service.php,但安卓模拟器的127.0.0.1指向模拟器自身,不是你的电脑本地服务器:
- 如果你用的是Android Studio自带模拟器,把地址改成
http://10.0.2.2/api/stock_service.php - 如果是Genymotion模拟器,改成
http://10.0.3.2/api/stock_service.php - 或者直接用你电脑的局域网IP地址(比如
192.168.1.105,可以通过ipconfig/ifconfig查询)
2. 检查安卓权限和明文HTTP设置
- 添加网络权限:在
AndroidManifest.xml里必须加上:<uses-permission android:name="android.permission.INTERNET" /> - 允许明文HTTP(Android 9+):如果你的服务器用的是HTTP而非HTTPS,需要在
AndroidManifest.xml的application标签里添加:android:usesCleartextTraffic="true"
3. 验证PHP接口是否正常返回JSON
用浏览器或Postman直接访问你的PHP接口地址,确认返回的是有效的JSON数组,比如:
[{"name":"股票A","price":"100"},{"name":"股票B","price":"200"}]
如果接口返回错误、空白或者非JSON格式,那App肯定无法解析。
二、完善代码的错误处理
你的代码里没有对网络请求失败的情况做判断,直接把null传给了JSON解析方法,这是触发NPE的直接原因,需要修改:
1. 在doInBackground里打印错误日志
把catch块改成这样,方便你查看具体的网络错误原因:
@Override protected String doInBackground(Void... voids) { try { URL url = new URL(urlWebService); HttpURLConnection con = (HttpURLConnection) url.openConnection(); // 添加超时设置,避免无限等待 con.setConnectTimeout(5000); con.setReadTimeout(5000); con.setRequestMethod("GET"); StringBuilder sb = new StringBuilder(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream())); String json; while ((json = bufferedReader.readLine()) != null) { sb.append(json); } return sb.toString().trim(); } catch (Exception e) { // 打印错误日志,方便排查问题 Log.e("DownloadJSON", "网络请求失败", e); return null; } }
2. 在onPostExecute里拦截空值
在调用loadIntoListView前,先判断返回的字符串是否为空:
@Override protected void onPostExecute(String s) { super.onPostExecute(s); // 先判断数据是否有效 if (s == null || s.isEmpty()) { Toast.makeText(getApplicationContext(), "数据加载失败,请检查网络或接口", Toast.LENGTH_LONG).show(); return; } try { loadIntoListView(s); } catch (JSONException e) { Toast.makeText(getApplicationContext(), "JSON格式错误", Toast.LENGTH_SHORT).show(); e.printStackTrace(); } }
3. 可选:在loadIntoListView里增加防御性判断
为了更稳妥,也可以在解析JSON前再加一层判断:
private void loadIntoListView(String json) throws JSONException { if (json == null || json.isEmpty()) { Toast.makeText(this, "无可用数据", Toast.LENGTH_SHORT).show(); return; } JSONArray jsonArray = new JSONArray(json); // 剩余代码不变... }
三、排查流程总结
- 先确保PHP接口能正常返回有效JSON
- 修正模拟器访问服务器的地址
- 确认安卓Manifest里的权限和明文HTTP设置正确
- 运行App,查看Logcat里的错误日志,定位具体网络问题
- 用完善后的错误处理代码避免NPE
内容的提问来源于stack exchange,提问作者Luca
相关产品推荐
相关产品推荐

