2013-03-08 10 views
8

Ho sofferto di questo problema per mesi e mesi (ma ora sono in fase di ottimizzazione delle prestazioni). Tuttavia, ora ho un disperato bisogno di sapere perché il mio adattatore sente che è necessario eseguire bindView fino a 4 volte su un disco.Personalizzazione dell'adattatore del cursore che chiama bindView più volte

Ho un adattatore del cursore personalizzato che popola un gridview.

Alcuni di debug per mostrare ciò che sta succedendo:

03-08 14:46:47.980: I/AdapterCursorGrid(20724): newView() 
03-08 14:46:48.470: I/AdapterCursorGrid(20724): bindView() 
03-08 14:46:48.570: I/AdapterCursorGrid(20724): -------------------------- 
03-08 14:46:48.570: I/AdapterCursorGrid(20724): bindView() Record Id: 1 
03-08 14:46:48.570: I/AdapterCursorGrid(20724): bindView() Cursor Position: 0 
03-08 14:46:48.570: I/AdapterCursorGrid(20724): bindView() View Type: 0 
03-08 14:46:48.570: I/AdapterCursorGrid(20724): -------------------------- 
03-08 14:46:48.600: D/AdapterCursorGrid(20724): bindView() Avatar empty... 
03-08 14:46:48.690: D/AdapterCursorGrid(20724): bindView() Picture creation... 
03-08 14:46:49.490: I/AdapterCursorGrid(20724): bindView() 
03-08 14:46:49.501: I/AdapterCursorGrid(20724): -------------------------- 
03-08 14:46:49.501: I/AdapterCursorGrid(20724): bindView() Record Id: 1 
03-08 14:46:49.501: I/AdapterCursorGrid(20724): bindView() Cursor Position: 0 
03-08 14:46:49.501: I/AdapterCursorGrid(20724): bindView() View Type: 0 
03-08 14:46:49.501: I/AdapterCursorGrid(20724): -------------------------- 
03-08 14:46:49.521: D/AdapterCursorGrid(20724): bindView() Avatar empty... 
03-08 14:46:49.521: D/AdapterCursorGrid(20724): bindView() Picture creation... 
03-08 14:46:50.320: I/AdapterCursorGrid(20724): newView() 
03-08 14:46:51.170: I/AdapterCursorGrid(20724): bindView() 
03-08 14:46:51.180: I/AdapterCursorGrid(20724): -------------------------- 
03-08 14:46:51.180: I/AdapterCursorGrid(20724): bindView() Record Id: 1 
03-08 14:46:51.180: I/AdapterCursorGrid(20724): bindView() Cursor Position: 0 
03-08 14:46:51.190: I/AdapterCursorGrid(20724): bindView() View Type: 0 
03-08 14:46:51.190: I/AdapterCursorGrid(20724): -------------------------- 
03-08 14:46:51.190: D/AdapterCursorGrid(20724): bindView() Avatar empty... 
03-08 14:46:51.200: D/AdapterCursorGrid(20724): bindView() Picture creation... 
03-08 14:46:51.870: I/AdapterCursorGrid(20724): bindView() 
03-08 14:46:51.896: I/AdapterCursorGrid(20724): -------------------------- 
03-08 14:46:51.896: I/AdapterCursorGrid(20724): bindView() Record Id: 1 
03-08 14:46:51.900: I/AdapterCursorGrid(20724): bindView() Cursor Position: 0 
03-08 14:46:51.900: I/AdapterCursorGrid(20724): bindView() View Type: 0 
03-08 14:46:51.900: I/AdapterCursorGrid(20724): -------------------------- 
03-08 14:46:51.900: D/AdapterCursorGrid(20724): bindView() Avatar empty... 
03-08 14:46:51.900: D/AdapterCursorGrid(20724): bindView() Picture creation... 

Il "Avatar vuoto ..." e "la creazione di immagine ..." è semplicemente di debug che mi dice che è l'elaborazione e l'aggiornamento 2 particolari ImageView s .

Perché o perché bindView si esegue così tante volte? Quali sono le ragioni di questo e cosa posso fare per risolvere questo?

Logicamente parlando mi aspetto che bindView venga eseguito una sola volta (e una volta ogni volta che si aggiorna la scheda), ho sbagliato a pensarlo?

+0

Qualunque sia "creazione Picture" è * non * dovrebbe essere sul thread dell'applicazione principale. 'bindView()' deve tornare in meno di 1 ms su un 'GridView', indipendentemente dal fatto che si ritenga che venga chiamato troppe volte per altri motivi. ** Spendere ~ 600 ms in "Creazione immagine" è pessimo **. Anche se 'bindView()' è stato chiamato solo una volta per cella, sarebbe chiamato MxN volte (righe M, colonne N) quando il 'GridView' è inizialmente popolato, il che significa che * l'interfaccia utente è bloccata per diversi secondi * all'inizio . – CommonsWare

+0

@CommonsWare Sì, lo otterrò con un'attività a sincronizzazione. – HGPB

risposta

13

Il sistema operativo può chiamare più volte bindView in modo che possa misurare e disporre correttamente l'elenco. Questo non è un bug tanto quanto deve essere. Questo, insieme alla fluidità dello scorrimento, è il motivo per cui le implementazioni di bindView devono essere il più efficienti possibile. Ci sono alcuni buoni consigli e trucchi che puoi usare dettagliati su Android Developers Page.

+1

Devo supporre che questo sia rilevante per un 'gridView'? – HGPB

+0

Sì. Android può chiamare questo numero tante volte quanto basta per misurare e impaginare correttamente il contenitore. – CaseyB

+0

Attualmente implemento il pattern ViewHolder. Aggiornerò l'elaborazione delle immagini in un task asincrono e quindi rivedrò 'bindView' di nuovo. La parte preoccupante è l'idea che il mio compito asincrono verrà avviato 4 volte nel suo stato attuale. Qualche altro suggerimento sul motivo per cui viene chiamato 4 volte? 'GridView' è impostato su fill_parent per altezza e larghezza. Testa grattata – HGPB

0

Una cosa che ho scoperto con ImageView è che modificando l'immagine si otterrà il ImageView per richiedere un layout a meno che l'immagine nuova e vecchia abbia esattamente le stesse dimensioni.

Internamente il ImageView utilizza getIntrinsicWidth() e getIntrinsicHeight() per capire se richiedere o meno un layout.

provare qualcosa di simile (anche se sarebbe più senso per inviare l'attuale larghezza/altezza al vostro carico async e ridimensionare il bitmap prima di tornare dal fondo):

public void replaceBitmap(ImageView iv, Bitmap bitmap) { 
    Drawable current = iv.getDrawable(); 
    if (bitmap.getWidth() != current.getIntrinsicHeight() 
      || bitmap.getHeight() != current.getIntrinsicHeight()) { 
     bitmap = Bitmap.createScaledBitmap(bitmap, 
      current.getIntrinsicWidth(), current.getIntrinsicHeight(), true); 
    } 
    iv.setImageBitmap(bitmap); 
} 
10

ho scoperto anche che Bindview era essere chiamato molte più volte del previsto. La mia altezza ListView è stata impostata su wrap_content. Dopo averlo modificato in match_parent, il numero di chiamate è diminuito drasticamente.

Credito per questa soluzione va alla risposta per questa domanda Custom CursorAdapater's bindView called 77 times...have I done something wrong?

+0

perché questa risposta non è stata ancora upvoted? Questa è una soluzione fantastica. – faizal

+0

Beh, non è tecnicamente una soluzione alla domanda posta. Volevo solo sottolineare che se stai vedendo bindView chiamato un numero eccessivo di volte, potrebbe essere perché l'altezza viene erroneamente impostata su wrap_content. – aaronmarino

+0

Grazie, hai salvato la mia giornata !! Questa risposta dovrebbe essere la risposta accettata :) –