2011-08-17 9 views
5

Ho un'app che sta facendo una quantità non trascurabile di download di immagini in miniatura e altre risorse da un servizio remoto.HttpClient si blocca per lunghi periodi di tempo, anche con i parametri di timeout impostati

Sto usando una singola istanza di DefaultHttpClient e una classe personalizzata che ho scritto che pianifica tutti i miei download. Tutto il download viene eseguito in serie su thread in background tramite AsyncTask. Non rieseguo la mia routine di download finché onPostExecute non viene eseguito in AsyncTask.

Questo spesso funziona perfettamente. Se metto in coda 20 immagini, il mio programmatore fa la cosa giusta. Tuttavia, mi imbatto in casi in cui la procedura si blocca appena al punto di chiamare client.execute (dove client è la mia istanza di DefaultHttpClient). Riesco a riesumare inspiegabilmente il processo navigando intorno all'app e facendo azioni casuali (scorrendo un elenco, navigando avanti e indietro tra le attività, ecc.). È come se qualcosa che sto facendo è inviare un messaggio di "sveglia" a un thread che si è bloccato o bloccato.

Ho aggiunto un'enorme quantità di registrazione a tutte le parti mobili della mia applicazione per vedere se qualcosa di esterno a questa procedura sta causando una sorta di condizione di deadlock. Vedo LogCat di pid per vedere se sta accadendo qualcos'altro nel mio processo al punto di stallo o al punto di ripresa, e non vedo nulla di fuori dall'ordinario. La parte più strana di questo è che posso ripetere l'esatta condizione più e più volte.

FWIW, ho impostato i timeout dei socket e i timeout delle connessioni sia sull'istanza HttpClient che sull'istanza HttpGet passata al metodo execute. Ciò non causa il ritorno del metodo execute o un'eccezione o qualcosa del genere. Quando la procedura "riprende", HttpClient.execute restituisce una HttpResponse valida e tutto funziona normalmente.

Qualche idea su cose che posso eseguire il debug per scoprire dove si sta facendo inciampare? Riconosco che questa è una condizione molto specifica, ma esistono metodi avanzati per il debug specifico di DefaultHttpClient o del traffico http in Android in generale?

Grazie!

risposta

5

Condividi lo stesso HttpClient attraverso i thread? Di default non è thread-safe, quindi potresti volerlo controllare. Molto probabilmente sta bloccando l'I/O, quindi dovresti fare qualche debugging. Si può usare qualcosa di simile per consentire HttpClient tronchi di dump filo:

Logger.getLogger("org.apache.http.wire").setLevel(Level.FINEST); 
Logger.getLogger("org.apache.http.headers").setLevel(FINEST); 
Logger.getLogger("httpclient.wire.header").setLevel(FINEST); 
Logger.getLogger("httpclient.wire.content").setLevel(FINEST); 

System.setProperty("org.apache.commons.logging.Log", 
    "org.apache.commons.logging.impl.SimpleLog"); 
System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true"); 
System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire", "debug"); 
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http", "debug"); 
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.headers", "debug"); 

Per abilitarla, eseguire i seguenti comandi di shell. I log dei fili verranno inviati a logcat:

adb shell setprop log.tag.org.apache.http VERBOSE 
adb shell setprop log.tag.org.apache.http.wire VERBOSE 
adb shell setprop log.tag.org.apache.http.headers VERBOSE 
+0

Grazie per la risposta ... difficile per ottenere risposte a domande così specifiche e prolisse. Ho intenzione di provare la registrazione, ma credo che tu mi abbia indicato nella giusta direzione comunque. Sto usando AsyncTask che mi dà thread da un pool di thread ... questo potrebbe causare alcuni problemi. Proverò una singola classe derivata da Thread quindi non c'è mai più di una chiamata simultanea a HttpClient.execute sui thread diff.Sarei disposto a scommettere che anche se eseguo i ritorni prima di eseguire nuovamente il mio loop, probabilmente c'è qualche ripulitura che non ha finito di funzionare prima che il thread successivo entri. – Rich

+0

Btw, ho aggiunto questo codice e non vedo eventuali registri aggiuntivi in ​​LogCat. C'è qualcosa di più in questo? Sta scaricando i log in un file, o dovrei vederlo in LogCat? – Rich

+0

Dovrebbe andare a logcat. Assicurati di eseguirlo prima del codice dell'app, come in un inizializzatore statico. –

-2

Ho avuto un problema simile prima. Quando provo a fare entrare in coda HTTP, il metodo httpClient.execute(get); non restituirà una risposta, come deadlock.

HttpResponse response = httpClient.execute(get); 
HttpEntity entity = response.getEntity(); 

Questo è il mio codice, e quello che faccio è chiamare entity.consumeContent(); allora funziona.

+0

In realtà non ha risposto alla domanda. –

Problemi correlati