开发附近地点展示App遇AsyncTask #2空指针崩溃求助
Android 附近地点App AsyncTask空指针崩溃问题修复
一、直接崩溃原因:InputStream空指针调用close()
从LogCat日志可以定位到崩溃发生在DownloadUrl.java第42行:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.io.InputStream.close()' on a null object reference
当网络请求出现异常(比如URL无效、网络断开、服务器返回错误码)时,inputStream = httpURLConnection.getInputStream()会抛出异常,导致inputStream未被赋值,仍然是null。进入finally块直接调用inputStream.close()就会触发空指针异常。
修复方法:修改DownloadUrl的finally块,先判空再关闭资源
finally { // 关闭InputStream前先判空 if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } // 断开连接前判断HttpURLConnection是否为空 if (httpURLConnection != null) { httpURLConnection.disconnect(); } }
二、FetchData中的JSON解析错误(潜在崩溃点)
在FetchData.java的onPostExecute方法中,存在两处致命逻辑错误:
- 错误将单个地点对象当成JSONArray处理
- 尝试将字符串"name"转为整数,会触发
NumberFormatException
JSONArray getName = jsonArray.getJSONArray(i); String name = getName.getString(Integer.parseInt("name"));
修复方法:正确从地点对象中获取名称
替换为:
String name = jsonObject1.getString("name");
同时,要先判断返回数据是否为空,避免JSONObject初始化失败:
@Override protected void onPostExecute(String s) { // 先处理空数据情况 if (s == null || s.isEmpty()) { // 可添加提示逻辑,比如Toast告知用户加载失败 return; } try{ JSONObject jsonObject = new JSONObject(s); JSONArray jsonArray= jsonObject.getJSONArray("results"); // Google Places API返回的数组键是"results"(复数) for (int i=0 ; i<jsonArray.length(); i++){ JSONObject jsonObject1 = jsonArray.getJSONObject(i); JSONObject getLocation = jsonObject1.getJSONObject("geometry") .getJSONObject("location"); String lat = getLocation.getString("lat"); String lng = getLocation.getString("lng"); String name = jsonObject1.getString("name"); LatLng latLng = new LatLng(Double.parseDouble(lat),Double.parseDouble(lng)); MarkerOptions markerOptions = new MarkerOptions(); markerOptions.title(name); markerOptions.position(latLng); googleMap.addMarker(markerOptions); googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,15)); } } catch (JSONException e) { e.printStackTrace(); // 避免直接抛出RuntimeException导致App崩溃 } }
三、额外优化与错误处理
- 添加必要权限:确保
AndroidManifest.xml中声明网络及定位权限(如果需要基于用户位置查找地点):
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
- 增强网络请求健壮性:在
DownloadUrl的retireveUrl方法中添加超时设置,并处理HTTP错误码:
try{ URL getUrl = new URL(url); httpURLConnection = (HttpURLConnection) getUrl.openConnection(); httpURLConnection.setRequestMethod("GET"); httpURLConnection.setConnectTimeout(5000); // 5秒连接超时 httpURLConnection.setReadTimeout(5000); // 5秒读取超时 httpURLConnection.connect(); // 检查HTTP响应码,仅处理200-299的成功响应 int responseCode = httpURLConnection.getResponseCode(); if (responseCode < 200 || responseCode >= 300) { Log.e("DownloadUrl", "HTTP Error Code: " + responseCode); return ""; } inputStream = httpURLConnection.getInputStream(); // ... 后续读取逻辑 }catch (Exception e){ Log.e("DownloadUrl", "Request failed: ", e); // 打印完整异常栈,方便排查问题 }
- 替换废弃组件:AsyncTask在Android 11(API 30)已被废弃,建议后续改用
Coroutines、Volley或Retrofit等现代网络框架,提升代码的可维护性和性能。
内容的提问来源于stack exchange,提问作者Yash Deshmukh
相关产品推荐
相关产品推荐

