Android Volley请求后全局列表size返回0,求技术协助
嘿,这个问题我太熟了!你遇到的核心问题是Volley的网络请求是异步执行的,咱们一步步来拆解解决:
问题根源
当你调用getdata()方法后,代码会立刻执行后续的逻辑(比如你去获取list.size()的那行代码),但此时网络请求还在后台跑,onResponse()方法还没被调用,list.add(cityWeather)自然也没执行,所以你拿到的size就是0。
解决方案
这里给你两种常用的解决方式,选适合你场景的就行:
1. 直接在onResponse里处理后续逻辑
既然onResponse是请求成功后才会触发的回调,那所有需要用到list数据的操作,都放在这个方法里就对了。比如你要更新UI、打印list大小,直接加在list.add(cityWeather)后面:
public void getdata(String cities) { String url = "http://api.openweathermap.org/data/2.5/weather?q=" + cities + "&APPID=8072ed7ede0fc9bcb8591a2a2eb90cfd"; StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse(String response) { try { CityWeather cityWeather = new CityWeather(); JSONObject object = new JSONObject(response); cityWeather.setLonitude(String.valueOf(object.getJSONObject("coord").getDouble("lon"))); cityWeather.setLatitude(String.valueOf(object.getJSONObject("coord").getDouble("lat"))); cityWeather.setCityName(object.getString("name")); cityWeather.setCurrentTemp(String.valueOf(object.getJSONObject("main").getDouble("temp"))); cityWeather.setPressure(String.valueOf(object.getJSONObject("main").getInt("pressure"))); cityWeather.setHumidity(String.valueOf(object.getJSONObject("main").getInt("humidity"))); cityWeather.setMinTemp(String.valueOf(object.getJSONObject("main").getDouble("temp_min"))); cityWeather.setMaxTemp(String.valueOf(object.getJSONObject("main").getDouble("temp_max"))); cityWeather.setWindSpeed(String.valueOf(object.getJSONObject("wind").getDouble("speed"))); cityWeather.setWindDegree(String.valueOf(object.getJSONObject("wind").getInt("deg"))); list.add(cityWeather); // 在这里处理list的后续操作,比如打印size或者更新UI Log.d("WeatherLog", "当前list大小:" + list.size()); // 如果是RecyclerView,这里可以调用 adapter.notifyDataSetChanged(); } catch (JSONException e) { Toast.makeText(MainActivity.this, e.getMessage().toString(), Toast.LENGTH_LONG).show(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show(); } }); RequestQueue queue = Volley.newRequestQueue(this); queue.add(request); }
2. 用回调接口解耦代码
如果你的后续逻辑不在当前Activity里,或者不想把所有代码都堆在onResponse里,可以定义一个回调接口,让请求完成后主动通知你:
首先定义回调接口:
public interface OnWeatherLoadedListener { void onSuccess(List<CityWeather> weatherList); void onFailure(String errorMessage); }
然后修改getdata方法,把回调传进去:
public void getdata(String cities, final OnWeatherLoadedListener listener) { String url = "http://api.openweathermap.org/data/2.5/weather?q=" + cities + "&APPID=8072ed7ede0fc9bcb8591a2a2eb90cfd"; StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { @Override public void onResponse(String response) { try { CityWeather cityWeather = new CityWeather(); JSONObject object = new JSONObject(response); // 省略赋值代码... list.add(cityWeather); // 请求成功,通知回调 listener.onSuccess(list); } catch (JSONException e) { String errorMsg = e.getMessage(); Toast.makeText(MainActivity.this, errorMsg, Toast.LENGTH_LONG).show(); listener.onFailure(errorMsg); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { String errorMsg = error.toString(); Toast.makeText(MainActivity.this, errorMsg, Toast.LENGTH_LONG).show(); listener.onFailure(errorMsg); } }); RequestQueue queue = Volley.newRequestQueue(this); queue.add(request); }
调用的时候这样用:
getdata("Shanghai", new OnWeatherLoadedListener() { @Override public void onSuccess(List<CityWeather> weatherList) { // 这里可以安全获取list的size了 Log.d("WeatherLog", "请求完成后list大小:" + weatherList.size()); // 处理你的业务逻辑,比如更新UI } @Override public void onFailure(String errorMessage) { // 处理请求失败的情况 } });
额外提醒
千万不要尝试用同步等待的方式(比如Thread.sleep()或者CountDownLatch)去等Volley请求完成,这样会导致主线程阻塞,触发ANR(应用无响应)错误,完全不符合Android的异步编程规范。
内容的提问来源于stack exchange,提问作者user9213317
相关产品推荐
相关产品推荐

