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

Android Studio中Volley填充ArrayList后跳转Activity时列表为空

问题分析与解决方案:Volley异步加载导致集合为空&跨Activity数据传递问题

咱们来拆解你遇到的问题,点击按钮时miListaPartidos为空,主要有两个核心原因,同时你的代码还有一个隐藏的坑,我一起给你说明:

一、为什么miListaPartidos会为空?

这是因为Volley的网络请求是异步执行的:
你在onCreate里调用了getPartidos(),但这个方法只是发起了网络请求,请求会在后台线程执行,而主线程会继续加载界面、渲染按钮。这时候如果用户在网络请求还没完成(也就是onResponse还没执行、集合还没被填充)的时候点击按钮,miListaPartidos自然是空的,就会触发你看到的错误。

二、隐藏的坑:跨Activity传递对象集合会失败

你的Partido类没有实现序列化接口(Parcelable或Serializable),就算miListaPartidos被成功填充,通过Intent.putExtra传递的时候也会报错,因为Android要求跨组件传递的对象必须是可序列化的。


对应的解决方案

1. 解决异步加载导致的集合为空问题

有两种常用的处理方式,你可以选适合自己的:

方式一:数据加载完成前禁用按钮

在onCreate初始化按钮后,先把所有按钮设置为不可点击,等网络请求完成、集合填充完毕后再启用:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_act1_1);
    
    // 初始化按钮
    btns1=findViewById(R.id.btns1);
    btns2=findViewById(R.id.btns2);
    // ...其他按钮同理
    btnE=findViewById(R.id.btnE);
    
    // 先禁用所有按钮
    btns1.setEnabled(false);
    btns2.setEnabled(false);
    // ...其他按钮都设置setEnabled(false)
    btnE.setEnabled(false);
    
    getPartidos();
}

然后在getPartidos()的onResponse方法里,循环填充完集合后启用按钮:

public void getPartidos(){
    RequestQueue requestQueue= Volley.newRequestQueue(this);
    JsonObjectRequest jSonObjectRequest=new JsonObjectRequest(Request.Method.GET,urlPartidos, null, 
        new Response.Listener<JSONObject>(){
            public void onResponse(JSONObject response){
                try{
                    JSONArray jsonArrayPartidos=response.getJSONArray("results");
                    if(jsonArrayPartidos.length()>0) {
                        for (int i = 0; i < jsonArrayPartidos.length(); i++) {
                            JSONObject jsonPartido = jsonArrayPartidos.getJSONObject(i);
                            final int id = jsonPartido.getInt("id");
                            final String detalles = jsonPartido.getString("details");
                            final String equipo1 = jsonPartido.getString("team1");
                            final String equipo2 = jsonPartido.getString("team2");
                            final int goles1 = jsonPartido.getInt("goals1");
                            final int goles2 = jsonPartido.getInt("goals2");
                            final Partido nuevoPartido = new Partido(id, detalles, equipo1, equipo2, goles1, goles2);
                            miListaPartidos.add(nuevoPartido);
                        }
                        // 数据加载完成,启用所有按钮
                        btns1.setEnabled(true);
                        btns2.setEnabled(true);
                        // ...其他按钮同理
                        btnE.setEnabled(true);
                    }
                } catch(JSONException je){
                    je.printStackTrace(); // 不要忽略异常,方便排查
                }
            }
        }, 
        new Response.ErrorListener() {
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace(); // 打印错误日志
                Toast.makeText(Act1_1.this, "数据加载失败,请检查网络", Toast.LENGTH_SHORT).show();
            }
        } 
    );
    requestQueue.add(jSonObjectRequest);
}

方式二:点击按钮时先判断集合状态

如果不想禁用按钮,可以在点击事件里先检查集合是否已加载完成,避免崩溃:

public void btnClick_Normal(View v){
    // 先判断集合是否为空,或者长度是否满足后续循环的要求
    if(miListaPartidos == null || miListaPartidos.size() < Integer.parseInt((String)v.getTag())*6){
        Toast.makeText(this, "数据还在加载中,请稍等", Toast.LENGTH_SHORT).show();
        return;
    }
    
    Intent intent=new Intent(getApplicationContext(),Act1_1_1.class);
    int id1=(Integer.parseInt((String)v.getTag()));
    ArrayList<Partido> listaEq=new ArrayList<>();
    for(int i=(((id1-1)*6)); i<=(id1*6)-1;i++ ) {
        listaEq.add(miListaPartidos.get(i));
    }
    intent.putExtra("listaEq", listaEq);
    startActivity(intent);
}

2. 解决跨Activity传递对象集合的问题

推荐给Partido类实现Parcelable接口(比Serializable效率更高,更适合Android场景):

import android.os.Parcel;
import android.os.Parcelable;

public class Partido implements Parcelable {
    private int id;
    private String detalles;
    private String equipo1;
    private String equipo2;
    private int goles1;
    private int goles2;

    public Partido(int id, String detalles, String equipo1, String equipo2, int goles1, int goles2){
        this.id=id;
        this.detalles=detalles;
        this.equipo1=equipo1;
        this.equipo2=equipo2;
        this.goles1=goles1;
        this.goles2=goles2;
    }

    // 从Parcel中读取数据的构造方法
    protected Partido(Parcel in) {
        id = in.readInt();
        detalles = in.readString();
        equipo1 = in.readString();
        equipo2 = in.readString();
        goles1 = in.readInt();
        goles2 = in.readInt();
    }

    // Parcelable必须的CREATOR常量
    public static final Creator<Partido> CREATOR = new Creator<Partido>() {
        @Override
        public Partido createFromParcel(Parcel in) {
            return new Partido(in);
        }

        @Override
        public Partido[] newArray(int size) {
            return new Partido[size];
        }
    };

    // 你的getter和setter方法保持不变
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getDetalles() { return detalles; }
    public void setDetalles(String detalles) { this.detalles = detalles; }
    public String getEquipo1() { return equipo1; }
    public void setEquipo1(String equipo1) { this.equipo1 = equipo1; }
    public String getEquipo2() { return equipo2; }
    public void setEquipo2(String equipo2) { this.equipo2 = equipo2; }
    public int getGoles1() { return goles1; }
    public void setGoles1(int goles1) { this.goles1 = goles1; }
    public int getGoles2() { return goles2; }
    public void setGoles2(int goles2) { this.goles2 = goles2; }

    // Parcelable接口要求实现的两个方法
    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(id);
        dest.writeString(detalles);
        dest.writeString(equipo1);
        dest.writeString(equipo2);
        dest.writeInt(goles1);
        dest.writeInt(goles2);
    }
}

之后在接收数据的Activity(比如Act1_1_1)里,这样获取集合:

ArrayList<Partido> listaEq = getIntent().getParcelableArrayListExtra("listaEq");

额外的优化建议

  • 不要忽略异常和错误回调:在JSONException和VolleyError的回调里添加printStackTrace()或者日志,方便你排查数据解析或网络问题。
  • 可以添加一个ProgressBar在界面上,网络请求时显示,请求完成后隐藏,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:07:58