2009-08-26 6 views
2

Diese Anwendung, an der ich gearbeitet habe, verfügt über Datenbanken mit mehreren Megabyte Daten, die durchsucht werden sollen. Viele der Aktivitäten sind lediglich ListViews, die durch verschiedene Datenebenen innerhalb der Datenbanken ablaufen, bis wir "Dokumente" erreichen, was nur HTML ist, das aus den DBs entnommen und auf dem Telefon angezeigt wird. Das Problem, das ich habe, ist, dass einige dieser Aktivitäten die Fähigkeit haben müssen, die Datenbanken zu durchsuchen, indem sie Tastenanschläge erfassen und die Abfrage mit einem "like% blah%" erneut ausführen. Dies funktioniert ziemlich schnell, außer wenn der Benutzer zuerst die Daten lädt und wenn der Benutzer zuerst einen Tastenanschlag eingibt. Ich benutze ein ResourceCursorAdapter und ich erzeuge den Cursor in einem Hintergrundthread, aber um eine listAdapter.changeCursor() zu machen, muss ich einen Handler verwenden, um es in den Haupt-UI-Thread zu posten. Dieser spezielle Anruf friert dann den UI-Thread gerade lang genug ein, um den gefürchteten ANR-Dialog aufzurufen. Ich bin gespannt, wie ich dies vollständig auf einen Hintergrund-Thread abladen kann, so dass die Benutzeroberfläche reaktionsschnell bleibt und keine ANR-Dialoge auftauchen.Android CursorAdapters, ListViews und Hintergrundthreads

Nur zur vollständigen Offenlegung, ich ursprünglich eine ArrayList der benutzerdefinierten Modellobjekte und die Verwendung eines ArrayAdapter zurück, aber (verständlicherweise) der Kunde wies darauf hin, es war schlechte Speicher-Management und ich war nicht mit der Leistung sowieso zufrieden. Ich möchte wirklich eine Lösung zu vermeiden, in denen ich riesige Listen von Objekten bin zu erzeugen und dann ein listAdapter.notifyDataSetChanged/Invalidated tun()

Hier ist der Code in Frage:

private Runnable filterDrugListRunnable = new Runnable() { 
    public void run() { 
     if (filterLock.tryLock() == false) return; 

     cur = ActivityUtils.getIndexItemCursor(DrugListActivity.this); 

     if (cur == null || forceRefresh == true) { 
      cur = docDb.getItemCursor(selectedIndex.getIndexId(), filter); 
      ActivityUtils.setIndexItemCursor(DrugListActivity.this, cur); 
      forceRefresh = false; 
     } 

     updateHandler.post(new Runnable() { 
      public void run() { 
       listAdapter.changeCursor(cur); 
      } 
     }); 

     filterLock.unlock(); 

     updateHandler.post(hideProgressRunnable); 
     updateHandler.post(updateListRunnable); 
    } 
}; 

Antwort

1

ich es finden schwer zu glauben, dass listAdapter.changeCursor() allein würde ausreichen, um eine ANR zu verursachen, vorausgesetzt, Sie erstellten die Cursor in einem Hintergrund-Thread. Es sollte nicht so viel Arbeit geben, die nötig ist, um eine Handvoll von Listenzeilen neu zu streichen. Ich würde überprüfen, ob die Arbeit, die Sie in Ihrem Handler machen, so begrenzt ist, wie Sie denken. Vielleicht überlegen Sie sich, eine AsyncTask zu verwenden, die es einfacher macht, die Hintergrundarbeit (doInBackground()) von der On-UI-Thread-Nachbearbeitung (onPostExecute()) zu trennen.

Sie können versuchen, ersetzen Sie den Adapter direkt, indem Sie setAdapter() erneut mit dem neuen Cursor in einem neuen Adapter verpackt aufrufen.

Sie können sehen, wie AutoCompleteTextView dieses Szenario behandelt, da es mit einer SpinnerAdapter on-the-fly-Filterung arbeitet. Vielleicht können einige ihrer Techniken in Ihrem Fall Anwendung finden.

+0

Bevor ich den changeCursor Anruf hinzugefügt, alles war glücklich und im Hintergrund lief. Einmal habe ich hinzugefügt, um diese: updateHandler.post (neu Runnable() { public void run() { listAdapter.changeCursor (Aktuell); } }); Alles ging schnell kaputt. – MattC

+0

Ungerade Frage: Was ist FilterLock in Ihrem obigen Code? Stößt du möglicherweise in eine tödliche Umarmung oder eine Sackgasse? – CommonsWare

+0

Es ist nur eine Sperre, die wir erwartet hatten, falls der Benutzer während der ersten Abfrage weiter tippte. Durch den tatsächlichen Code des CursorAdapter, ChangeCursor ruft notifyDataSetChanged() und das ist, wo es hängt. – MattC

Verwandte Themen