2012-01-26 3 views
5

Ho 6 diversi tipi di risultati List dopo aver completato AsyncTask. E i risultati devono essere restituiti a Activity. Ad esempio: List<A>, List<B>, List<C>, List<D>, List<E> e infine List<F>.Come restituire Elenco anonimo o ArrayList su AsyncTask in Android

Questo è il mio AsyncTask:

public class myAsync extends AsyncTask<String, String, List> { 

    private List resultList; 

    @Override 
    protected List doInBackground(String... params) { 
     //params[0] is url 
     //params[1] is type 
     callAPI api = new callAPI(params[0], params[1]); 
     // According to type api decides type of List and generates 
     return api.getJSON(); // returns a List which already parse JSON 
    } 

    @Override 
    protected void onPostExecute(List result) { 
     // Result is here now, may be 6 different List type. 
     this.resultList = result 
    } 

    // returns result 
    public List getResultList() { return this.resultList; } 
} 

chiamerò AsyncTask come questo:

myAsync task = new myAsync(); 
task.execute(params); 
List myList = task.getResultList(); // type is uncertain 
Log.d("Tag", Integer.toString(myList.size()); 

Sai, devo sottolineare il tipo di ritorno (Risultato) tra < tag>. Se scelgo un tipo specifico per List, non funziona con altri tipi.

Infatti, ho già provato a restituire List<Object> e solo i tipi List. Ma non ha funzionato.

Non voglio utilizzare 6 diversi Async. È possibile risolvere questo con un solo AsyncTask? Immagino di aver bisogno di una lista anonima o qualcosa di simile a non essere sicuro. Qualcuno può spiegarlo?

+0

È possibile ignorare <>, non sarà un errore, semplicemente avverte. – kosa

+0

Vuoi dire che dovrei usare questa definizione: 'AsyncTask '. Se lo è, quali saranno i tipi di ritorno? Ho già restituito tutti i tipi come Elenco normale, ottenuto un errore NullException. –

+0

Post stacktrace qui, ho il sospetto che il NullPointer che si sta ricevendo potrebbe provenire da qualche altra parte. – kosa

risposta

9

In primo luogo, vorrei sottolineare che la sequenza in cui si sta ottenendo l'elenco è non corretta. Permettetemi di dimostrare:

// Initialize myAsync 
myAsync task = new myAsync(); 

// This will do work for some period of time, this statement DOES NOT 'block' 
// till myAsync completes, it will run it in the background 
task.execute(params); 

// This will return null because by the time you get here, task.execute most 
// likely hasn't finished yet. 
task.getResultList(); 

Edit: Ora che hai incluso quello che vuole a che fare con il risultato lista, ecco come si potrebbe modificare il metodo di onPostExecute:

@Override 
protected void onPostExecute(List result) { 
    Log.d(TAG, "The returned list contains " +result.size()+ "elements"); 
    // Do anything else you need to with the returned list here 
} 

Così per riassumere, se è necessario fare qualcos'altro con gli elenchi restituiti (oltre a stampare le loro dimensioni), ad esempio confrontare, stampare elementi, ecc., è necessario farlo nel metodo onPostExecute.

+0

Ci scusiamo per l'errore di sintassi. Ovviamente deve essere task.getResultList(). Corretto ora E hai ragione, è presto per il metodo getResultList(). Come posso chiamare? –

+1

@OgulcanOrhan Proprio come ho fatto notare nella tua domanda [precedente] (http://stackoverflow.com/a/9019395/1101070), di solito vuoi usare il metodo 'onPostExecute' del tuo AsyncTask per _do qualunque cosa tu abbia bisogno fare_ con la lista (s). Modifica la tua domanda per includere ciò che fai _do_ con 'task.getResultList()' e posso darti una risposta migliore. –

+0

Aggiornamento 'doInBackground' e' onPostExecute'. Spero sia chiaro ora. –

2

A seconda del contenuto dell'elenco (Cosa sono A, B, C, ecc.), È possibile creare un'interfaccia per loro.

Quindi se A, B, C ecc sono oggetti, è possibile creare un'interfaccia che chiamiamo ListContentInterface. Ognuno dei tuoi elementi deve quindi implementare ListContentInterface. È quindi possibile indicare il tipo:

List<ListContentInterface>. 

Dopo di che si può quindi verificare quali sono i contenuti della lista è davvero, prendendo il primo elemento della lista, e il controllo della sua classe:

if(element.getClass() == ClassToTestFor.class) ... 

Se gli oggetti hanno metodi in comune, è necessario specificarli nell'interfaccia. Se hanno TUTTI i metodi in comune, è possibile utilizzare direttamente l'Elenco, senza testare la classe degli oggetti (Poiché tutti possono fare ciò che definisce l'interfaccia).

Spero che abbia senso per voi. Potrebbe non essere il miglior uso delle interfacce o la soluzione migliore, ma potrebbe risolvere il tuo problema.

+0

Sì, potrei riuscire a creare un'interfaccia per questi 6 oggetti diversi, e lo farò. Ma cosa cambierà? Non ho potuto capire i prossimi passi. –

+2

Quando si dispone di tutti gli elementi in un'interfaccia, è possibile creare un elenco contenente oggetti che implementano tale interfaccia. In questo modo puoi usare lo stesso tipo di lista, per tutti i tuoi oggetti. Dopodiché, se devi fare qualcosa di specifico per i diversi tipi di elementi, puoi semplicemente rimuovere gli elementi dall'elenco e verificare quale classe sono, prima di eseguire la logica specifica dell'oggetto. –

0

Sto risolvendo questo tipo di problema usando execute(). Get();

Esempio

call from activity 

    ArrayList<String> arraylistitem= new jsonparsing(getActivity()).execute().get(); 

    In async task 

    public class jsonparsing extends AsyncTask<Void, Void, ArrayList<String>> 
    { 
    public jsonparsing(Activity activity) 
     { 
      this.activity = activity; 
      arraylistitem = new ArrayList<String>();   
     } 

     protected ArrayList<String> doInBackground(Void... arg0) 
     { 
       // Do anything else you need to with the returned list here 
      return arraylistitem; 
      } 
    }