2012-04-11 4 views
6

Desidero sapere come utilizzare lo CursorLoader per popolare i widget su uno schermo. Tutti gli esempi online sono solo per l'utilizzo di un adattatore e questo funziona alla grande. Quello di cui ho bisogno è un modo affidabile per aggiornare le visualizzazioni nel mio schermo da un cursore e sul thread dell'interfaccia utente e senza a volte andare in crash a causa di StaleDataException o il cursore viene disattivato all'improvviso. Ecco il mio approccio attuale ma ricevo ancora alcuni rapporti sugli arresti anomali degli utenti.Popolare i widget da un cursore in onLoadFinished()

@Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle arg1) { 
     CursorLoader loader = null; 

     switch (id) { 
      case LOADER_ID_DATA: 
       loader = new CursorLoader(...); 
       break; 
     } 

     return loader; 
    } 

    @Override 
    public void onLoadFinished(Loader<Cursor> loader, final Cursor cursor) { 
     handler.post(new Runnable() { 

      @Override 
      public void run() { 
       if (getActivity() == null) 
        return; 

       updateView(cursor); 
      } 
     }); 
    } 

    @Override 
    public void onLoaderReset(Loader<Cursor> arg0) { 
    } 

Una soluzione sarebbe quella di recuperare tutti i campi cursore direttamente all'interno onLoadFinished e li passa al gestore per popolare i widget sul thread UI. Ma questo è brutto perché potrei avere molti valori nel cursore. Mi piacerebbe trovare un modo affidabile e senza incidenti per affrontare tutto questo.

+0

"Una soluzione sarebbe quella di recuperare tutti i campi del cursore direttamente all'interno di onLoadFinished e passarli tutti al gestore per popolare i widget sul thread dell'interfaccia utente" - "onLoadFinished()" viene chiamato sul thread dell'applicazione principale. – CommonsWare

+0

@CommonsWare Per quanto ne so, onLoadFinished non viene chiamato sul thread dell'interfaccia utente principale. Se si guarda ad esempio al codice sorgente di android-protips_location scritto da Reto Meier, usa un gestore per popolare i widget con i valori. E il suo commento sopra onLoadFinished() è che pianifica un aggiornamento sul thread dell'applicazione principale. –

+0

Citazione di Reto Meier: "Si noti che onLoadFinished non è sincronizzato con il thread dell'applicazione principale, quindi sto estraendo i valori del cursore sullo stesso thread del cursore, prima di pubblicare un nuovo Runnable sul thread dell'interfaccia utente che assegna quelli nuovi valori agli elementi dell'interfaccia utente " –

risposta

7

Dopo aver chiesto su # android-dev SimonVT e readme mi ha aiutato a ottenere il fondo di questo.

Non c'è nulla che afferma che onLoadFinished sarà chiamato sul thread dell'interfaccia utente, quindi in teoria si dovrebbe usare un Handler come consigliato nel libro di Reto. Tuttavia, quando si utilizza un CursorLoader (che è di gran lunga il caso d'uso più comune) si può praticamente garantire che onLoadFinished sarà chiamato nel thread dell'interfaccia utente.

+3

Il motivo per "praticamente" è che CursorLoader utilizza un AsyncTask per eseguire il lavoro in background, che utilizza un gestore statico per postback e infine chiama onLoadFinished. Se chiami LoaderManager.initLoader (...) dal thread principale, il gestore è garantito per essere collegato anche al thread principale. Perché questo Handler non sia collegato al thread principale, dovresti creare un Thread con un Looper e avviare il Loader da lì. – SimonVT