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

Android新手求助:Volley解析后ArrayList始终为空

问题分析与解决方案

嘿,刚接触Android和Stack Overflow完全没问题,咱们一步步来搞定你的问题~

你的核心问题在于Volley的网络请求是异步执行的:当你调用getList()的时候,代码会立刻把空的parseItemList返回给HomeFragment,而Volley的onResponse()方法要等网络请求完成后才会执行(这时候才会填充列表)。所以你拿到的永远是初始的空列表。

解决方案:用回调接口处理异步结果

最适合新手理解的方式是定义一个回调接口,让JsonParse在请求完成后主动把数据传递给HomeFragment,而不是同步返回。

步骤1:定义回调接口

先创建一个接口,用来传递请求成功/失败的结果:

public interface OnDataLoadedListener {
    void onDataLoaded(ArrayList<ParseItem> itemList);
    void onError(String errorMessage);
}

步骤2:修改JsonParse类

把getList()改成接收回调的方法,去掉返回值,在请求完成后通过回调传递数据:

public class JsonParse {
    Context context;
    String json_url = "myurl";

    public JsonParse(Context context) {
        this.context = context;
    }

    // 改为接收回调接口,不再直接返回列表
    public void getList(final OnDataLoadedListener listener) {
        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.POST, json_url, null,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        ArrayList<ParseItem> parseItemList = new ArrayList<>();
                        for (int i = 0; i < response.length(); i++) {
                            try {
                                JSONObject jsonObject = response.getJSONObject(i);
                                ParseItem parseItem = new ParseItem();
                                String naslov = jsonObject.getString("naslov");
                                String url = jsonObject.getString("url");
                                parseItem.setTitle(naslov);
                                parseItem.setUrl(url);

                                JSONArray niz = jsonObject.getJSONArray("niz");
                                ArrayList<String> podnaslovTMP = new ArrayList<>();
                                ArrayList<String> podurlTMP = new ArrayList<>();
                                for (int j = 0; j < niz.length(); j++) {
                                    JSONObject nizOBJ = niz.getJSONObject(j);
                                    String podnaslov = nizOBJ.getString("podnaslov");
                                    String podurl = nizOBJ.getString("podurl");
                                    podnaslovTMP.add(podnaslov);
                                    podurlTMP.add(podurl);
                                }
                                // 把临时子列表设置给ParseItem(记得你的ParseItem类要有对应getter/setter)
                                parseItem.setPodnaslovList(podnaslovTMP);
                                parseItem.setPodurlList(podurlTMP);
                                parseItemList.add(parseItem);
                            } catch (JSONException e) {
                                e.printStackTrace();
                                listener.onError("解析JSON出错:" + e.getMessage());
                            }
                        }
                        // 请求成功,通过回调传递数据
                        listener.onDataLoaded(parseItemList);
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
                listener.onError("网络请求失败:" + error.getMessage());
            }
        });
        MySingleton.getInstance(context).addToRequestQueue(jsonArrayRequest);
    }
}

步骤3:修改HomeFragment调用逻辑

在Fragment里调用getList()时,传入回调接口实现,在回调里获取数据并更新UI:

public class HomeFragment extends Fragment implements View.OnClickListener {
    private Context context;
    private static final int REQUEST_CALL = 1;
    private View view;
    private ArrayList<ParseItem> arrayList = new ArrayList<>();

    public HomeFragment() {
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_home, container, false);
        init();
        JsonParse jsonParse = new JsonParse(getActivity());
        
        // 调用getList并传入回调
        jsonParse.getList(new OnDataLoadedListener() {
            @Override
            public void onDataLoaded(ArrayList<ParseItem> itemList) {
                // 请求成功,获取到填充好的列表
                arrayList = itemList;
                // 这里可以更新你的UI,比如设置RecyclerView适配器
                // 注意:更新UI前要确保Fragment处于活跃状态,避免崩溃
                if (isAdded()) {
                    // 示例:recyclerView.setAdapter(new MyCustomAdapter(arrayList));
                }
            }

            @Override
            public void onError(String errorMessage) {
                // 请求失败,提示用户
                if (isAdded()) {
                    Toast.makeText(getActivity(), errorMessage, Toast.LENGTH_SHORT).show();
                }
            }
        });
        return view;
    }

    // 你的init()和onClick()方法...
}

额外提醒

  • 异步操作的核心就是不能同步等待结果,必须通过回调、LiveData、协程等方式处理后续逻辑
  • 在回调里更新UI时,一定要检查Fragment是否还附着在Activity上(比如用isAdded()),避免内存泄漏或空指针异常
  • 如果以后想更优雅地处理异步,可以学习Jetpack的LiveData或者Kotlin协程,不过先把回调的逻辑搞懂是基础~

内容的提问来源于stack exchange,提问作者ShoneBl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 13:22:35