Java, Android / 将值存储在数组列表中,但列表为空

Java, Android / Stored values in an arraylist, but list is empty

我将数据库中的数据存储到名为 nameList 的数组列表中。

在函数 'get_spinner_info' 中,值已成功存储在 nameList 中。

但是,此函数之外的 nameList 没有任何值。

错误代码是 “ java.lang.IndexOutOfBoundsException:索引:0,大小:0”。

我真的需要你的帮助。


public class my_Item {
    private Context context;
    private FirebaseDatabase firebaseDatabase = FirebaseDatabase.getInstance();
    DatabaseReference datebaseReference = firebaseDatabase.getReference();
    ArrayList<String> nameList = new ArrayList<String>();

    
    // Get the value from the database and put them in the 'nameList'.
    //In this code, I can successfully check the value within the 'nameList'.
    public void get_spinner_info(String brand, String item, String prod_key){
        datebaseReference.child(brand).child(item).child(prod_key).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for (DataSnapshot ds : dataSnapshot.child("myValue").getChildren()) {
                    String prod_name = ds.getValue().toString();  
                    nameList.add(prod_name);
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });
    }


    // But the nameList is empty in this part.
    public void callFunction(final String brand, final String item, final String product_name, final String product_key, final int product_Num) {
        get_spinner_info(brand, item, product_key);
        Log.d("Spinner namelist :  ", nameList.get(0));
    }
}

get_spinner_info 方法启动并加载异步数据(注册 lsitener),因此 onDataChange 将在 Log.d("Spinner nameList : ", nameList.get(0));

之后被调用

您的数据只有在 onDataChange 调用后才可用,这可能需要一些时间。 get_spinner_info 刚刚开始加载您的数据,并不意味着所有数据在方法调用结束后立即可用

将其放在 onDataChange 的末尾(在当前 for 循环之后)以检查数组 available/present 中的项目

for (String name : nameList) Log.d("Spinner", "name: " + name);

同步问题导致此类错误

如果您已有数据,请执行此操作

创建界面class

public interface DataCallback {
    public void reciveData(ArrayList<String> nameList ,boolean isOk);
}

在你的classmy_Item中这样调用接口

    public void get_spinner_info(String brand,String item,String prod_key,DataCallback callback){
            datebaseReference.child(brand).child(item).child(prod_key).addListenerForSingleValueEvent(new ValueEventListener(){
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot){
            for(DataSnapshot ds:dataSnapshot.child("myValue").getChildren()){
            String prod_name=ds.getValue().toString();
            nameList.add(prod_name);
            }
            // here you should check if the result available or NOT to prevent null exceptions 
            if(nameList.size()>0){
            callback.reciveData(nameList,true);// true and false used to check data if available or null
            }
            else{
            callback.reciveData(nameList,false);
                            
                            }
            }
    @Override
    public void onCancelled(@NonNull DatabaseError databaseError){

               }
                });
   }

现在当您调用 get_spinner_info 时,您需要这样的回调

get_spinner_info(brand, item, product_key,new DataCallback() {
    @Override
    public void callback(ArrayList<String> nameList, boolean isOk) {
        if (isOk){
            /// you have all data recived
            Log.d("Spinner namelist :  ", nameList.get(0));
        }else {

            // no data available
            Log.i("TAG", "callback: No Data Available");
        }
    }
}););