2017-04-12 4 views
1

Wenn ich viele Elemente abfragen die Benutzeroberfläche einfrieren.Android Realm findAllAsync() einfrieren UI

realm.where(TVRealm.class).equalTo("favorite", true).findAllAsync() 
       .addChangeListener(new RealmChangeListener<RealmResults<TVRealm>>() { 
        @Override 
        public void onChange(RealmResults<TVRealm> element) { 
         List<TV> tvList = new ArrayList<>(); 
         for (TVRealm tvRealm : element) { 
          tvList.add(prepareTV(TVRealm.toTV(tvRealm), true)); 
         } 
         listener.onDataChange(tvList); 
        } 
       }); 

Ich dachte, dass findAllAsync() auf anderen Thread ausgeführt wird und das Problem vermeiden, aber nicht. Weiß jemand, wie man dieses Problem vermeidet? Vielleicht gibt es einen anderen Weg, ohne findAllAsync() -Methode zu verwenden.

Danke.

+0

Welche Realm-Version verwenden Sie? – beeender

+1

Ihre Benutzeroberfläche reagiert nicht mehr, da Ihre Zuordnungslogik im UI-Thread stattfindet und für jedes einzelne Element ausgewertet wird - nicht, weil Realm langsam ist. Realm wurde nicht dafür entworfen, jedes einzelne Element in einer Schleife lesen zu lassen; Deshalb ist "RealmResults" standardmäßig nur ein "lazy-loaded" -Cursor, der Ihnen Lazy-Loaded-Proxies – EpicPandaForce

+1

gibt, so dass die Lösung darin besteht, Ihren Code so zu überarbeiten, dass 'tvList.add (prepareTV (TVRealm.toTV (tvRealm), wahr)); 'wird nicht da sein und einfach' TVRealm' direkt verwenden – EpicPandaForce

Antwort

1

Wenn ich keinen Fehler mache, während RealmResults aktualisiert wird, erstellen Sie für jede Änderung eine neue Sammlung mit neuen Modellen und aktualisieren Sie die Benutzeroberfläche. Versuchen Sie findAll() in einem anderen Thread aufzurufen, ordnen Sie die Ergebnisse TVs zu und senden Sie die fertige Liste der TVs an den UI-Thread.

2

Laut offiziellen Realm Dokument, findAllAsync arbeitet in einem Hintergrund-Thread.

Ich denke, dass Ihre Daten zu oft ändern und Sie versuchen, zu oft zu benachrichtigen. Du blockierst also UI. Ich schätze, Sie melden einen RecyclerView Adapter in Ihrer onDataChange Methode.

Auch wenn Ihre Ergebnisliste zu viele Elemente enthält, kann jedes Mal, wenn Ihre Daten sich geändert haben, das Durchsuchen der Ergebnisse und das Hinzufügen von Elementen zu einer neuen Liste ui blockieren.

+0

Die Daten ändern sich nicht oft, es passiert, wenn ich das Fragment erstelle. Ich habe ein Schubladenlayout, wenn ich eine Schubladenoption auswähle, ändere ich das Fragment. Wenn die Schublade zu schließen beginnt, friert die App für einen Moment ein, dann wird das Fragment korrekt geladen. – Sol

+0

beim Öffnen/Schließen Schublade ein Fragment auffüllen und ersetzen kann es für einen Moment blockieren. Eine der einfachsten Möglichkeiten, dies zu vermeiden. Sie können einfach warten, bis die Schublade geschlossen wird, und nach dem Schließen können Sie Ihr Fragment ersetzen. – savepopulation