2013-05-04 19 views
5

Sto avendo una certa confusione su come utilizzare gli ascoltatori per passare informazioni tra classi e attività.Evento di trigger quando AsyncTask è completo utilizzando Listener

Lo scenario è questo:
Ho un'attività che legge i dati da un database Sqlite e inserisce questi dati in un ArrayList che viene passato a un Adattatore che quindi lo visualizza sullo schermo.

La domanda:
La mia app si arresta in modo anomalo quando tento di aggiornare l'interfaccia del listener con un valore. Non mostra nulla nel logcat ... si blocca semplicemente l'app. Qualcuno potrebbe gentilmente indicare dove sto andando male. - Grazie

Dettagli:
Ho l'elaborazione del database eseguita da una classe chiamata DatbaseRoutines e al suo interno un metodo interno che esegue il sollevamento pesi. il metodo utilizza AsyncTask per non intrattenere il thread principale.

ho creato e interfaccia con un solo metodo

public interface DatabaseProcessListener { 
    public void ProcessingIsDone(boolean blnProcessIsFinished); 
} 

Nella mia classe DatabaseRoutines sto creando una variabile privata

private DatabaseProcessListener dbProcesslistener; 

insieme ad un setter per esso

public void setDbProcesslistener(DatabaseProcessListener dbProcesslistener) { 
    this.dbProcesslistener = dbProcesslistener; 
    } 

Al termine dell'elaborazione, utilizzo il metodo PostExecute per aggiornare Listener in modo che ciò possa avvenire modificare il valore in chi ascolta su True (vale a dire che l'elaborazione db è fatto) sotto è il codice

  protected void onPostExecute(Boolean aBoolean) { 
       super.onPostExecute(aBoolean); 
       dialog.dismiss(); //i have progress dialog during processing and its       
       //closed here 

       if (blnUpdateSucceededStatus) 
       { 
        dbProcesslistener.ProcessingIsDone(true); 
        } 
        else 
        { 
        Toast.makeText(ctx, "Transactions Processing 
        failed",Toast.LENGTH_SHORT); 
        } ; 

Infine nell'attività visualizzazione dei dati raccolti dal database che implementano l'ascoltatore. vedi sotto.

public class MyActivity extends Activity implements DatabaseProcessListener 
{ 

@Override 
public void ProcessingIsDone(boolean blnProcessIsFinished) { 
    if(blnProcessIsFinished){ 
     PopulateExpandableListView(); 
    } 
    public void PopulateExpandableListView() { 
    //code for populating the listview goes here; 
    } 
} 

dopo qualche scavo ho trovato il logcat error..its un'eccezione nullpointer

05-05 11:11:18.590: ERROR/AndroidRuntime(22339): FATAL EXCEPTION: main 
    java.lang.NullPointerException 
    at com.example.mledger.DatabaseRoutines$1.onPostExecute(DatabaseRoutines.java:258) 
    at com.example.mledger.DatabaseRoutines$1.onPostExecute(DatabaseRoutines.java:141) 
    at android.os.AsyncTask.finish(AsyncTask.java:631) 
    at android.os.AsyncTask.access$600(AsyncTask.java:177) 
    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:137) 
    at android.app.ActivityThread.main(ActivityThread.java:4921) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:511) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805) 
    at dalvik.system.NativeStart.main(Native Method) 

Purtroppo l'applicazione è appeso e l'interfaccia non aggiorna l'attività che visualizza i dati con il vero (vale a dire l'elaborazione viene eseguita)

Mi punti nella giusta direzione. - Grazie

+1

Hai controllato se OnPostExecute() stato chiamato per il vostro AsyncTask. – Anirudh

+0

Sì, l'ho fatto. Inserisco un breakpoint e si blocca solo sulla linea chiamando l'ascoltatore. grazie – KuriaNdungu

risposta

3

Hai la risposta! Non stavo inizializzando l'ascoltatore nella mia classe chiamata. tutto quello che dovevo fare è stato messo in questa linea

db.setDbProcesslistener(this); 

cioè

DatabaseRoutines db = new DatabaseRoutines(MyActivity.this); 
db.setDbProcesslistener(MyActivity.this); 

ed è iniziato a lavorare.

Grazie a tutti coloro che hanno guardato e ho cercato di pensare alla soluzione :)

+0

@ KuriaNdungu - GRAZIE per aver pubblicato ciò che DID funziona. Grazie ANCHE per il FINE JOB di mostrare abbastanza del tuo codice che TUTTI ora possono provare ad applicare questa tecnica. – DSlomer64

+0

AH, UOMO !!!!!! Tutto ciò che ho fatto è stato meditare e tagliare i primi 3 e 5 hunk del codice di @ Kuria nella mia app e modificato il mio 'onPostExecute' per avere una riga -' dbProcesslistener.ProcessingIsDone (true); 'e poi ho ottenuto NPE, quindi Mi sono svegliato e incollato nella sua linea per soddisfare la mia 'app':' dbc.setDbProcesslistener (this); 'E HA FUNZIONATO. STUDIARE QUESTO ESEMPIO di una tecnica MOLTO importante. SUPER JOB, Kuria !! Questo è esemplificativo SO Q e (USER'S!) Funzionante A! – DSlomer64

+0

@ DSlomer64 1) inizia la domanda 2) upvote erythang 3) avvia una taglia e consegnala a Kuria. – Will

3

Suoni come la variabile dbProcesslistener è NULL. Chiami il tuo setter e passa un oggetto Listener inizializzato qualche tempo prima di invocare dbProcesslistener.ProcessingIsDone(true);?

+0

Grazie. quello era in realtà il problema. non stavo inizializzando prima di invocare. – KuriaNdungu

+0

Aveva dimenticato. Fatto ora :) – KuriaNdungu