Android Studio中天气APP输入城市后崩溃的空指针问题求助
Android天气APP查询闪退:NullPointerException问题解决
问题核心
闪退的直接原因是convertJSONtoArrayList方法中调用forecast.getJSONArray("list")时,forecast对象为null,触发空指针异常。而forecast来自AsyncTask的返回值,说明网络请求未成功获取有效数据。
分步修复方案
1. 修复API URL构建错误
你的createURL方法存在两处关键错误:API密钥占位符无效、URL参数拼接格式错误,导致请求地址无效,服务器返回错误数据。
修改后的代码:
private URL createURL(String city) { String apiKey = "你的OpenWeatherMap密钥"; // 替换为你实际申请的API密钥 String baseURL = "http://api.openweathermap.org/data/2.5/forecast/daily?q="; try { // 按OpenWeatherMap接口规范拼接参数 String urlString = baseURL + URLEncoder.encode(city, "UTF-8") + "&units=metric" + // 可选,获取摄氏温度,可根据需求删除 "&appid=" + apiKey; return new URL(urlString); } catch (Exception e) { e.printStackTrace(); } return null; }
2. 增加空值检查,避免空指针
在convertJSONtoArrayList方法开头添加空值判断,防止直接操作null对象:
private void convertJSONtoArrayList(JSONObject forecast) { weatherList.clear(); // 先判断forecast是否为空 if (forecast == null) { Snackbar.make(findViewById(R.id.coordinatorLayout), "获取天气数据失败", Snackbar.LENGTH_LONG).show(); return; } try { JSONArray list = forecast.getJSONArray("list"); // 原有解析代码保持不变 for (int i = 0; i < list.length(); ++i) { JSONObject day = list.getJSONObject(i); JSONObject temperatures = day.getJSONObject("temp"); JSONObject weather = day.getJSONArray("weather").getJSONObject(0); weatherList.add(new Weather( day.getLong("dt"), temperatures.getDouble("min"), temperatures.getDouble("max"), day.getDouble("humidity"), weather.getString("description"), weather.getString("icon"))); } } catch (JSONException e) { e.printStackTrace(); Snackbar.make(findViewById(R.id.coordinatorLayout), "解析天气数据出错", Snackbar.LENGTH_LONG).show(); } }
3. 修复AsyncTask中的UI操作违规
doInBackground是后台线程,不能直接调用Snackbar(UI操作必须在主线程执行),需将错误信息传递到主线程处理:
@SuppressWarnings("deprecation") @SuppressLint("StaticFieldLeak") private class GetWeatherTask extends AsyncTask<URL, Void, JSONObject> { private String errorMsg; @Override protected JSONObject doInBackground(URL... params) { HttpURLConnection connection = null; errorMsg = null; try { connection = (HttpURLConnection) params[0].openConnection(); int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { StringBuilder builder = new StringBuilder(); try (BufferedReader reader = new BufferedReader( new InputStreamReader(connection.getInputStream()))) { String line; while ((line = reader.readLine()) != null) { builder.append(line); } } catch (IOException e) { errorMsg = "读取天气数据失败"; e.printStackTrace(); } return new JSONObject(builder.toString()); } else { errorMsg = "连接失败,响应码:" + responseCode; } } catch (Exception e) { errorMsg = "无法连接到OpenWeatherMap"; e.printStackTrace(); } finally { if (connection != null) { connection.disconnect(); } } return null; } @Override protected void onPostExecute(JSONObject weather) { // 先处理错误信息 if (errorMsg != null) { Snackbar.make(findViewById(R.id.coordinatorLayout), errorMsg, Snackbar.LENGTH_LONG).show(); return; } convertJSONtoArrayList(weather); weatherArrayAdapter.notifyDataSetChanged(); weatherListView.smoothScrollToPosition(0); } }
4. 修复Toolbar初始化问题
你的setSupportActionBar方法是空实现,无法正确设置Toolbar,修改为:
private void setSupportActionBar() { Toolbar toolbar = findViewById(R.id.toolbar); super.setSupportActionBar(toolbar); }
总结
主要问题是URL构建错误导致网络请求失败,返回null后未做空值检查触发闪退。按上述步骤修复后,即可解决查询天气时的闪退问题。
内容的提问来源于stack exchange,提问作者stepback3
相关产品推荐
相关产品推荐

