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

AsyncTask中生成的ArrayList无法填充ListView问题解决方案

问题根因

你在AsyncTask的子线程中完成网络请求、JSON解析、数据插入集合的逻辑后,没有通知绑定ListView的适配器数据已更新,适配器不会主动重新拉取集合数据渲染界面,这是异步加载数据后列表不显示的核心原因。

补充说明:你在onCreate中手动添加数据能正常显示,是因为setAdapter执行时集合里已经存在数据,适配器首次初始化就能拿到正确的数据集长度和内容;而异步任务的网络请求存在耗时,等数据插入集合时适配器早就完成了首次渲染,没收到刷新通知自然不会更新界面。

另外你代码里还有三个小问题:

  • 网络连接、输入流没有在finally块统一释放,日志里的A resource failed to call close警告就是资源泄漏导致的
  • AsyncTask里把name/height/mass定义成了类成员变量,循环复用时如果出现并发容易出现数据错乱
  • 日志拼接时name和height之间没加空格,打印内容会连在一起
修复方法
  1. 给CharacterGetData重写onPostExecute方法,这个方法会在doInBackground执行完成后自动切回主线程,在方法内调用适配器的notifyDataSetChanged()方法,通知列表刷新即可。
  2. 把流、连接的释放逻辑移到finally块,避免资源泄漏。
  3. 把循环内用到的name/height/mass变量移到for循环内部声明,避免值覆盖问题。
修正后的核心代码
// 仅贴修改后的AsyncTask部分,其余代码不需要改动
class CharacterGetData extends AsyncTask<String, Integer, String> {
    @Override
    protected String doInBackground(String... strings) {
        HttpURLConnection connection = null;
        BufferedReader in = null;
        try {
            URL obj = new URL("https://swapi.dev/api/people/?format=json");
            connection = (HttpURLConnection) obj.openConnection();
            connection.setRequestMethod("GET");

            in = new BufferedReader(
                    new InputStreamReader(connection.getInputStream()));
            String line;
            StringBuffer response = new StringBuffer();
            while ((line = in.readLine()) != null) {
                response.append(line);
            }

            JSONObject jsonObj = new JSONObject(response.toString());
            JSONArray jsonArray = jsonObj.getJSONArray("results");

            for (int i = 0 ; i < jsonArray.length(); i++) {
                JSONObject characterObj = jsonArray.getJSONObject(i);
                // 变量移到循环内部声明,避免多线程下值覆盖
                String name = characterObj.getString("name");
                String height = characterObj.getString("height");
                String mass = characterObj.getString("mass");
                Character character1 = new Character(name,height,mass);
                characterArray.add(character1);
                // 补空格优化日志显示
                Log.i("MainActivity", "The name is " + character1.name + " the height is " + character1.height);
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException | JSONException e) {
            e.printStackTrace();
        } finally {
            // 统一释放资源
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
        return null;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        // 主线程通知适配器刷新
        adapter.notifyDataSetChanged();
    }
}

补充提示:AsyncTask在Android 11及以上版本已被官方废弃,正式项目开发建议使用协程、Retrofit等更稳定的异步网络方案。

内容的提问来源于stack exchange,提问作者newbie-coder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 01:39:20