Restituisce i dati da AsyncTask Android

Ho cercato di fare una domanda simile su SO, ma non ho avuto alcun aiuto.

Nella mia applicazione Android, sto pensando di implementare Citazione Recente che l'utente ha visitato, cioè simile alle pagine visitate di recente sul web.

  • PAYMENT_CREATION_ERROR in PayPal iOS & Android SDK
  • Può un broadcastReceiver catturare più trasmissioni?
  • Errore: WatchActivity non può essere risolto a un tipo, perché lo sto ottenendo?
  • Modificare il nome / numero di telefono del contatto in modo programmato
  • Può essere testata un'applicazione a pagamento in alpha / beta gratuitamente
  • Il codice Dagger che dà NoClassDefFoundError quando Espresso Test sono eseguiti, il funzionamento normale funziona bene
  • Di seguito sono riportti i passi che segue:

    1.) Ogni volta che l'utente apre una vista aziendale, recuperare i simboli aziendali dal database

    2.) Memorizzare quindi il simbolo corrente con dataTime nel database.

    3.) Per tutti i simboli prelevati dal database, recuperare il current value e %Change e visualizzare il nome della società, il valore corrente e% Change in un elenco.

    Il problema si presenta nella class ASyncTask poiché il metodo postExecute non consente che il tipo di return sia diverso da quello void .

    Sto facendo qualcosa di sbagliato?

    Qualsiasi aiuto sarà risparmio di vita !!!

     String[] rsym,rcmp,rchg; rdbM = new RecentDBManager(CompanyView.this); try { Calendar date1 = Calendar.getInstance(); SimpleDateFormat dateformatter = new SimpleDateFormat( "dd/MM/yyyy HH:mm:ss"); String currentdate = dateformatter.format(date1.getTime()); rdbM.openDB(); //STEP 1 rsym = rdbM.getRecent_sym(); //STEP 2 rdbM.setData(currentsymbol, currentdate); rdbM.closeDB(); } catch (Exception e) { throw new Error(" *** ERROR in DB Access *** "+ e.toString()); } //STEP 3 for(int i=0;i<rsym.length;i++) { DownloadRecentQuote quotetask = new DownloadRecentQuote(); recentquotetask .execute(new String[] { "http://abc.com/stockquote.aspx?id=" + rsym[i] }); //CURRENT VALUE and %CHANGE which should be returned from ASyncTask class rcmp[i]=valuearr[0]; rchg[i]=valuearr[1]; } list1 = new ArrayList<HashMap<String, String>>(); HashMap<String, String> addList1; for (int i = 0; i < limit; i++) { addList1 = new HashMap<String, String>(); addList1.put(RecentSym_COLUMN, rsym[i]); addList1.put(RecentCMP_COLUMN, rcmp[i]); addList1.put(RecentChg_COLUMN, rchg[i]); list1.add(addList1); RecentAdapter adapter1 = new RecentAdapter( CompanyView.this, CompanyView.this, list1); listrecent.setAdapter(adapter1); } private class DownloadRecentQuote extends AsyncTask<String, Void, String> { /* Fetching data for RecentQuote information */ @Override protected String doInBackground(String... urls) { String response = ""; for (String url : urls) { DefaultHttpClient client = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(url); try { HttpResponse execute = client.execute(httpGet); InputStream content = execute.getEntity().getContent(); BufferedReader buffer = new BufferedReader( new InputStreamReader(content)); String s = ""; while ((s = buffer.readLine()) != null) { response += s; } } catch (Exception e) { e.printStackTrace(); } } return response; } @Override protected void onPostExecute(String result) { arr1 = result.split("@"); if (arr1[0].length() != 0) { if (arr1[0].equals("1")) { arr = arr1[1].split(";"); //RETURN 2 STRINGS String valuearr[]; valuearr[0] = arr[3]; valuearr[1] = arr[6].concat("%"); //return valuearr; } } } 

  • <La tua applicazione> ha problemi con i servizi di Google Play - Quando utilizza GoogleApiClient, innesca sempre onConnectionFailed
  • Come select valori distinti da una colonna nella tabella?
  • Come determinare se un WebView viene ingrandito completamente
  • Come mostrare l'image nella row di tabella in base alla dimensione
  • android.support.v4.widget.SwipeRefreshLayout funziona ma non è visibile
  • Differenza tra system.gc () e runtime.gc ()
  • 3 Solutions collect form web for “Restituisce i dati da AsyncTask Android”

    postExecute () non può restituire un valore perché chi o cosa tornerebbe? Il metodo originale che ha richiamato l'AsyncTask è stato eliminato perché l'AsyncTask è in esecuzione in background. È significato asincrono quando AsyncTask.execute () restituisce che è ancora in esecuzione in background, e quindi postExecute () non può restituire un valore perché non c'è niente da restituire.

    Invece la tua AsyncTask necessita di un riferimento all'attività o ad un altro object in modo da poter submit i tuoi valori. Nel codice il codice dopo le chiamate execute () non può essere presente perché il tuo task non è ancora finito. Invece dovresti creare un metodo denominato updateSymbol (currentPrice, percentChange), spostare tutto quel codice sottostante eseguire (), e nella tua AsyncTask dovresti passare un riferimento all'attività. Quindi chiamate updateSymbol (currentPrice, percentChange) dal metodo onPostExecute ().

    Tuttavia, fare attenzione se si dispone di un riferimento a un'attività che può essere distrutto mentre il tuo doInBackground () è in esecuzione e quando viene eseguito postExecute () dovrebbe solo abbandonare i risultati o non tentare di aggiornare l'interface utente. Ad esempio, l'utente ruota il proprio telefono per causare l'distruzione dell'attività. Trovo che sia meglio tenere un riferimento all'AsyncTask nell'attività in modo da poter annullare () se l'attività viene distrutta. È ansible call AsyncTask.cancel () quindi verificare se l'attività è stata annullata come:

     public void postExecute( String result ) { if( !isCanceled() ) { // do your updating here activity.setSymbol( result ); } } 

    È veramente facile creare una class di base per tutte le Attività in modo da poter facilmente tenere traccia di AsyncTasks in esecuzione:

     public class BaseActivity extends Activity { List<AsyncTask> runningTasks; public void onStop() { for( AsyncTask task : runningTasks ) { task.cancel(true); } } public AsyncTask start( AsyncTask task ) { runningTasks.add( task ); return task; } public void done( AsyncTask task ) { runningTasks.remove( task ); } } 

    Alcuni puntatori rapidi. Non è necessario eseguire (nuova string [] {"blah" + blah}). I varargs in Java consentono di farlo. eseguire ("blah" + blah). Anche tu stai prendendo delle eccezioni e continuando a non gestirle veramente. Sarà difficile quando qualcosa accade veramente perché la tua app li cattura e continua come se non fosse successo nulla. Se si verifica un errore, è ansible fornire qualche risposte all'utente e smettere di tentare di eseguire tale process. Arrestare, mostrare un errore all'utente e far loro fare la prossima cosa. Spostare i blocchi di cattura verso il basso dei methods.

    In sostanza, AsyncTask.onPostExecute () è where fare tutto quello che vuoi fare dopo che doInBackground () di AsyncTask viene eseguito e il risultato dell'esecuzione viene restituito. Questo dovrebbe essere considerato la best practice.

    Quando AsyncTask () execute () viene chiamato dal thread UI (nota che questo metodo deve essere chiamato dal thread UI), il framework Android crea un thread di lavoro e inizia a eseguire ciò che hai scritto in AsyncTask.doInBackground () su questo lavoratore filo. A questo punto (dopo aver chiamato nuovo AsyncTask () eseguire ()), il thread UI continua ad eseguire il codice dopo il nuovo AsyncTask () execute (). Così ora durante il tempo di esecuzione, hai due thread (UI e thread di lavoro) entrambi in esecuzione contemporaneamente.

    Ma where e quando viene riportto il risultato dell'esecuzione di AsyncTask dal thread del lavoratore al thread UI?

    Il punto in cui il thread di lavoratore (doInBackground ()) finisce e ritorna al thread UI è AysncTask.onPostExecute (). Questo metodo è garantito per essere chiamato dal framework sul thread dell'interface utente non appena AsyncTask finisce. In altre parole, non ci interessa where e quando AsyncTask.onPostExecute () viene chiamato in fase di esecuzione, abbiamo solo bisogno di garantire che sarà chiamato in ultima analisi in qualche fase in futuro. Questo è il motivo per cui questo metodo non restituisce un risultato di esecuzione, ma richiede che il risultato dell'esecuzione venga passato come unico parametro di metodo da doInBackground ().

    Inoltre, l'API Android fornisce un modo per restituire un risultato di esecuzione AsyncTask all'ora di codifica, AsyncTask.get () :

     MyAsyncTask myAsyncTask = new MyAsyncTask(); // This must be called from the UI thread: myAsyncTask.execute(); // Calling this will block UI thread execution: ExecutionResult result = myAsyncTask.get(); 

    Ricorda che AsyncTask.get () blocca l'esecuzione del thread di chiamata e probabilmente riceverai un'exception ANR se lo chiami sul thread UI. Questo è il carico utile di utilizzare AsyncTask.get (), chiamandolo sul thread UI, in realtà stai facendo eseguire sincronizzando il thread AsyncTask (filo lavoratore) con il thread UI (facendo attendere il thread UI). Riassumendo, questo è ansible ma non è consigliato.

    Solo per futuri riferimenti, perché questo post è un po 'vecchio:

    Ho creato una class Activity che dispone di un metodo onStart () e di una class separata per l'AsyncTask. Sulla base del mio test, dopo il metodo doInbackground () il risultato verrà inviato all'attività prima e dopo che verrà eseguito onPostExecute (). Ciò è dovuto al fatto che basata su logcat, ho primi dati di risposta (inviati dal server) innanzitutto, questa risposta verrà mostrata nuovamente dall'attività e l'ultimo messaggio visualizzato in onPostExecute ().

    Codice dell'attività:

     @Override protected void onStart() { super.onStart(); String str = "***"; if(isConnectedToInternet()){ myAsyncTask.execute(); try { if(myAsyncTask.get()) str = myAsyncTask.getResponseMsg(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } catch (CancellationException e) { e.printStackTrace(); } } Log.i("Data returned by server2:", str); } 

    Codice di AsyncTask:

     public class MyAsyncTask extends AsyncTask<Void, Void, Boolean> { private URL url; private HttpURLConnection conn; private String strResponseMsg; public MyAsyncTask(String url) throws MalformsdURLException{ this.url = new URL(url); } @Override protected void onPreExecute() { Log.i("Inside AsyncTask", "myAsyncTask is abut to start..."); } @Override protected Boolean doInBackground(Void... params) { boolean status = false; try { conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(Manager.ConnTimeout); conn.setReadTimeout(Manager.ReadTimeout); int responseCode = conn.getResponseCode(); Log.i("Connection oppened", "Response code is:" + responseCode); if (responseCode == HttpURLConnection.HTTP_OK) { BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); if (in != null) { StringBuilder strBuilder = new StringBuilder(); // Read character by character int ch = 0; while ((ch = in.read()) != -1) strBuilder.append((char) ch); // Showing returned message strResponseMsg = strBuilder.toString(); Log.i("Data returned by server:", strResponseMsg); status = true; } in.close(); } } catch (IOException e) { e.printStackTrace(); } return status; } @Override protected void onPostExecute(Boolean result) { Log.i("Inside AsyncTask", "myAsyncTask finished its task. Returning data to caller..."); } public String getResponseMsg(){ return strResponseMsg; } } 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.