Volley JsonObjectRequest无响应求助:回调函数未触发
Volley JsonObjectRequest无响应、回调未触发的排查与解决
已添加日志追踪代码执行流程,尝试过单独创建JsonObjectRequest对象传入、改用POST方法、单独编写请求函数等方式,但Volley的JsonObjectRequest仍无响应,回调函数未被调用。
原代码片段
private void getWeatherInfo(String cityName) { String url = "http://api.weatherapi.com/v1/forecast.json?key=38c8359999e8407bbd7170418223007&q="+cityName+"&days=1&aqi=no&alerts=no"; Log.d("Inside getWeatherInfo-", "API - "+url); cityName_textView.setText(cityName); Log.d("Inside getWeatherInfo-", "City name - "+cityName); RequestQueue queue = Volley.newRequestQueue(MainActivity.this); Log.d("Inside getWeatherInfo-", String.valueOf(queue)); JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { Log.d("Inside JsonObjRqst--", String.valueOf(response)); loadingPB.setVisibility(View.GONE); homeRL.setVisibility(View.VISIBLE); weatherRVModelArrayList.clear(); try { String temperature = response.getJSONObject("current").getString("temp_c"); temperature_textView.setText(temperature + "°C"); int isDay = response.getJSONObject("current").getInt("is_day"); String condition = response.getJSONObject("current").getJSONObject("condition").getString("text"); String conditionIcon = response.getJSONObject("current").getJSONObject("condition").getString("icon"); Picasso.get().load("http:".concat(conditionIcon)).into(icon_imageView); weatherCondition_textView.setText(condition); if (isDay == 1) { // 白天 Picasso.get().load("https://img.freepik.com/free-photo/fluffy-clouds-windy-sky_23-2148824925.jpg?w=2000").into(background_imageView); } else { // 夜晚 Picasso.get().load("https://images.unsplash.com/photo-1535418126925-0bfb3a0ee0d7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1yZWxhdGVkfDJ8fHxlbnwwfHx8fA%3D%3D&w=1000&q=80").into(background_imageView); } JSONObject forecastObj = response.getJSONObject("forecast"); JSONObject forecast = forecastObj.getJSONArray("forecastday").getJSONObject(0); JSONArray hourArray = forecast.getJSONArray("hour"); for(int i=0; i<hourArray.length(); i++) { JSONObject hour = hourArray.getJSONObject(i); String time = hour.getString("time"); String temper = hour.getString("temp_c"); String img = hour.getJSONObject("condition").getString("icon"); String windSp = hour.getString("wind_kph"); weatherRVModelArrayList.add(new WeatherRVModel(time, temper, img, windSp)); } weatherRVAdapter.notifyDataSetChanged(); } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(MainActivity.this, "请输入有效的城市名称", Toast.LENGTH_SHORT).show(); } }); queue.add(jsonObjectRequest); }
排查与解决步骤
- 确认网络权限:检查AndroidManifest.xml中是否添加了
<uses-permission android:name="android.permission.INTERNET"/>,Volley必须依赖该权限发起网络请求,没有的话直接添加。 - 修复URL与明文请求限制:
- 原URL使用HTTP协议,Android 9及以上系统默认禁止明文HTTP请求,直接将URL改为HTTPS(weatherapi支持HTTPS):
https://api.weatherapi.com/v1/forecast.json?key=... - 若必须使用HTTP,需在
res/xml目录下创建network_security_config.xml,配置允许该域名的明文请求,再在Manifest的application标签中添加android:networkSecurityConfig="@xml/network_security_config"。
- 原URL使用HTTP协议,Android 9及以上系统默认禁止明文HTTP请求,直接将URL改为HTTPS(weatherapi支持HTTPS):
- 增强错误日志:原ErrorListener仅弹出Toast,无法定位具体问题,修改后打印详细错误信息,包括状态码、响应数据,方便排查:
@Override public void onErrorResponse(VolleyError error) { Log.e("VolleyError", "请求错误:" + error.getMessage()); if (error.networkResponse != null) { Log.e("VolleyError", "状态码:" + error.networkResponse.statusCode); Log.e("VolleyError", "响应数据:" + new String(error.networkResponse.data)); } Toast.makeText(MainActivity.this, "请输入有效城市名或检查网络", Toast.LENGTH_SHORT).show(); } - 优化RequestQueue生命周期:不要每次调用方法都创建新的RequestQueue,建议全局单例持有,避免重复创建导致资源浪费或请求异常。
- 检查混淆配置:如果开启了ProGuard,需在
proguard-rules.pro中添加Volley的混淆规则,防止代码被混淆导致请求失败:-keep class com.android.volley.** { *; } -keep class com.android.volley.toolbox.** { *; } -keep class org.apache.commons.logging.** { *; }
修正后的代码片段
private void getWeatherInfo(String cityName) { // 改用HTTPS避免明文请求限制 String url = "https://api.weatherapi.com/v1/forecast.json?key=38c8359999e8407bbd7170418223007&q="+cityName+"&days=1&aqi=no&alerts=no"; Log.d("Inside getWeatherInfo-", "API - "+url); cityName_textView.setText(cityName); Log.d("Inside getWeatherInfo-", "City name - "+cityName); // 建议全局单例RequestQueue,避免重复创建 RequestQueue queue = Volley.newRequestQueue(MainActivity.this); Log.d("Inside getWeatherInfo-", String.valueOf(queue)); JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { Log.d("Inside JsonObjRqst--", String.valueOf(response)); loadingPB.setVisibility(View.GONE); homeRL.setVisibility(View.VISIBLE); weatherRVModelArrayList.clear(); try { String temperature = response.getJSONObject("current").getString("temp_c"); temperature_textView.setText(temperature + "°C"); int isDay = response.getJSONObject("current").getInt("is_day"); String condition = response.getJSONObject("current").getJSONObject("condition").getString("text"); String conditionIcon = response.getJSONObject("current").getJSONObject("condition").getString("icon"); Picasso.get().load("http:".concat(conditionIcon)).into(icon_imageView); weatherCondition_textView.setText(condition); if (isDay == 1) { // 白天背景 Picasso.get().load("https://img.freepik.com/free-photo/fluffy-clouds-windy-sky_23-2148824925.jpg?w=2000").into(background_imageView); } else { // 夜晚背景 Picasso.get().load("https://images.unsplash.com/photo-1535418126925-0bfb3a0ee0d7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1yZWxhdGVkfDJ8fHxlbnwwfHx8fA%3D%3D&w=1000&q=80").into(background_imageView); } JSONObject forecastObj = response.getJSONObject("forecast"); JSONObject forecast = forecastObj.getJSONArray("forecastday").getJSONObject(0); JSONArray hourArray = forecast.getJSONArray("hour"); for(int i=0; i<hourArray.length(); i++) { JSONObject hour = hourArray.getJSONObject(i); String time = hour.getString("time"); String temper = hour.getString("temp_c"); String img = hour.getJSONObject("condition").getString("icon"); String windSp = hour.getString("wind_kph"); weatherRVModelArrayList.add(new WeatherRVModel(time, temper, img, windSp)); } weatherRVAdapter.notifyDataSetChanged(); } catch (JSONException e) { e.printStackTrace(); Log.e("JSONParseError", "解析失败:" + e.getMessage()); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e("VolleyError", "请求错误:" + error.getMessage()); if (error.networkResponse != null) { Log.e("VolleyError", "状态码:" + error.networkResponse.statusCode); Log.e("VolleyError", "响应数据:" + new String(error.networkResponse.data)); } Toast.makeText(MainActivity.this, "请输入有效的城市名称或检查网络", Toast.LENGTH_SHORT).show(); } }); queue.add(jsonObjectRequest); }
内容的提问来源于stack exchange,提问作者Vansh Shah
相关产品推荐
相关产品推荐

