2

Ich habe eine Android-Chat-App, die alle Nachrichten sowohl in lokalen SQLite DB und in der Firebase Realtime DB speichert.Android Firebase Listener in onBindViewHolder von recyclerview

Wenn ich die Nachrichten in RecyclerView anzeige, frage ich sie aus meiner lokalen Datenbank ab (da einige zusätzliche Daten lokal gespeichert sind, die nicht in der Echtzeit-DB gespeichert sind).

Ich brauche eine Echtzeit-Aktualisierung der angezeigten Nachricht senden und lesen Status, die ich von der Echtzeit-DB erhalten.

Ist es in Ordnung, einen Wert Ereignis-Listener für jede Nachricht in der OnBindViewHolder Recycler-Ansicht festzulegen? .

So kann ich nur auf Änderungen in den Nachrichten hören, die zur Zeit auf dem Bildschirm angezeigt werden und nicht die gesamte Liste der Nachrichten vom Server erhalten (genau das, was ich brauche)

2 Fragen: - Ist diese Lösung in Ordnung oder gibt es einen besseren Weg? - Ich muss die Listener für Elemente entfernen, die in der Recycleransicht nicht sichtbar sind. Wie mache ich das?

Ich benutze nicht die FirebaseUI (ich weiß, dass es mein Problem löst), aber ich möchte die Daten von meiner lokalen Datenbank und nicht vom Server präsentieren und nur Updates auf einem Feld von der Firebase erhalten Echtzeit DB.

Antwort

1

Ist diese Lösung in Ordnung oder gibt es einen besseren Weg?

Ja und nein! Ich hätte dir die FirebaseUI vorgeschlagen, die definitiv die beste Option ist, aber du hast bereits erwähnt, dass du das nicht nutzen willst. Mit der Tatsache, FirebaseUI nicht zu verwenden, scheint dies die beste Option zu sein. [Ich würde vorschlagen, dass Sie direkt von Firebase-Leuten, die Ihnen die genaue Antwort geben können, Bewertungen dazu nehmen.] Sie sollten auch wissen, wenn Sie die Rückrufe nicht entfernen, sobald die Ansicht aus dem Bildschirm herauskommt, werden Sie enden mit Hunderten und Tausenden von Zuhörern (die meisten von ihnen redundant) baumeln und essen die Erinnerung wirklich nichts tun.

Ich muss die Listener für Elemente entfernen, die in der Recycleransicht nicht sichtbar sind. Wie mache ich das?

Ziemlich einfach. Sie können die onViewDetachedFromWindow(MyViewHolder holder) Methode von recyclerView verwenden, die Ihnen den Handler gibt, der gerade aus der Ansicht entfernt werden soll. Sie können diesen Aufruf verwenden, um den Rückruf zu entfernen.

Wie?

Die Sache ist - Sie benötigen eine Referenz Ihres Rückrufs, um es aus dem Ort zu entfernen. Sie können dies auf zwei Arten tun. Wenn Sie zu viele verschiedene Listener haben, können Sie eine hashmap erstellen, die alle Ihre Listener verfolgen kann. Bei Bedarf können Sie die Referenz Ihres Zuhörers abrufen und entfernen.

Der andere Weg ist:

@Override 
public void onBindViewHolder(final MyViewHolder holder, int position) { 
    User user = data.get(position); 
    holder.name.setText(user.Name); 
    holder.surname.setText(user.Surname); 
    holder.id = user.id; //Id is same as the key used to point this user. 
    holder.followers.setText("Loading.."); 
    DatabaseReference userFollowers = mRef.child(holder.id).child("Followers"); 
    followListener = new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      holder.followers.setText(String.valueOf(dataSnapshot.getValue())); 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 

     } 
    }; 
    userFollowers.addValueEventListener(followListener); //Adds a listener 
} 

@Override 
public void onViewDetachedFromWindow(MyViewHolder holder) { 
    DatabaseReference followRef = mRef.child(holder.id).child("Followers"); 
    followRef.removeEventListener(followListener); //Removes the listener 
    super.onViewDetachedFromWindow(holder); 
} 

Der Kodex könnte kleinere Fehler haben, ich habe es mit dieser Frage in Übereinstimmung geschrieben haben. Havent getestet.Aber ich hoffe, du hast die Idee.

Das Problem: [Auch dieses Ding hat ein kleines Problem, wer ich bin immer noch beste Lösung, die versuchen zu finden]: Wenn man die Aktivität schließen, die die recyclerView enthält, wird die Funktion onViewDetachedFromWindow(MyViewHolder holder) nicht für die Elemente gecallt auf Bildschirm zu dieser bestimmten Zeit. Wenn die Aktivität recyclerView endet, werden daher wenige Rückrufe (wie die Anzahl sichtbarer Elemente auf dem Bildschirm) nicht entfernt.

Sogar ich habe kürzlich in Firebase-Datenbank getaucht. Alle Verbesserungen/Vorschläge zur Antwort sind willkommen.

Verwandte Themen