You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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"。
  • 增强错误日志:原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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 13:06:23