android – Why my constructor in RecyclerView is getting called late?-ThrowExceptions

Exception or error:

I am creating a recyclerView for my project for which I am using 2 functions in onCreate,

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cart);
        System.out.println("dsdsds");
        pref = getSharedPreferences("pref", Context.MODE_PRIVATE);
        dbReff = FirebaseDatabase.getInstance().getReference().child("CartItem");
        dbToken = FirebaseDatabase.getInstance().getReference().child("TokenNumber");

        CreateList();
        BuildRecyclerView(); 
    } 

Here I am creating a list which is set in adapter in the first function,

cartItemArrayList = new ArrayList<>();

        dbReff.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for (DataSnapshot data : dataSnapshot.getChildren()) {
                    if(!data.child("name").getValue().toString().equals("notToDisplayThisItem")) {
                        cartItemArrayList.add(new CartItemIdQuant(
                                data.child("id").getValue().toString(),
                                data.child("quant").getValue().toString(),
                                data.child("name").getValue().toString(),
                                data.child("price").getValue().toString()
                        ));
                        Log.e("THE DATA", data.toString());
                    }
                }
                Log.e("INHERE","");
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });
    }

and the 2nd function is as followed,

recyclerView = findViewById(R.id.recyclerCartView);
        recyclerView.setHasFixedSize(true);
        layoutManager = new LinearLayoutManager(this);
        cartAdapter = new CartAdapter(cartItemArrayList);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(cartAdapter);
log.e("Message"," from build recyclerVIew");

and my class for the data item is as followed,

public class CartItemIdQuant {
    private String ID;
    private String Quant;
    private String Name;
    private String Price;

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    public String getPrice() {
        return Price;
    }

    public void setPrice(String price) {
        Price = price;
    }

    public String getID() {
        return ID;
    }

    public void setID(String ID) {
        this.ID = ID;
    }

    public String getQuant() {
        return Quant;
    }

    public void setQuant(String quant) {
        Quant = quant;
    }

    public CartItemIdQuant(String NewID, String NewQuant,String NewName,String NewPrice){
        ID = NewID;
        Quant = NewQuant;
        Name = NewName;
        Price = NewPrice;
        Log.e("the" , "Method Called From Constructor");

    }

    public CartItemIdQuant(){

    }
}

here the log of Data that I receive and print in the 1st function is printed and the log I print in the constructor is then printed after 2 seconds. I want to know the reason for the delay in the call, as I have to put a delay for it to work properly which I do not want.
Please help me, thank you in advance.

EDIT:
here as per the comment, is the logcat in which the message from the 2nd function is called before the list could be created.

2020-02-21 15:20:03.434 547-547/com.chinuEvent.chinuevent E/Message: from build recyclerVIew
2020-02-21 15:20:03.837 547-547/com.chinuEvent.chinuevent E/the: Method Called From Constructor
2020-02-21 15:20:03.838 547-547/com.chinuEvent.chinuevent E/THE DATA: DataSnapshot { key = 02, value = {price=15, name=Orange, id=02, quant=3} }
How to solve:

It is actually completely normal to set the adapter to the view before the data is loaded. In many cases (some of) the data is loaded (or modified) asynchronously, and you’ll often want to show those updates as they come in.

All you need to do for that is notify the adapter that its underlying data has changed. The adapter will then notify the view(s), and those will repaint with the updated data.

To notify the adapter, call its notifyDataSetChanged() in your onDataChange handler after you’ve modified cartItemArrayList:

dbReff.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        for (DataSnapshot data : dataSnapshot.getChildren()) {
            if(!data.child("name").getValue().toString().equals("notToDisplayThisItem")) {
                cartItemArrayList.add(new CartItemIdQuant(
                    data.child("id").getValue().toString(),
                    data.child("quant").getValue().toString(),
                    data.child("name").getValue().toString(),
                    data.child("price").getValue().toString()
                ));
            }
        }
        cartAdapter.notifyDataSetChanged();
    }
    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        throw databaseError.toException(); // never ignore possible errors
    }
});

Leave a Reply

Your email address will not be published. Required fields are marked *