2013-05-17 11 views
10

Uso il caricatore di immagini universale e ottengo un numero piuttosto elevato di immagini che non riescono a caricare per gli utenti ogni giorno. Sto usando questo codice per ottenere i miei errori di analisi.Universal Image loader non riesce a caricare le immagini a volte

public void onLoadingFailed(String imageUri, View view, FailReason failReason) { 
    try 
    { 
    String fail = failReason.getType().toString(); 
    String fail4 = failReason.getCause().toString(); 
    String sum = fail + " " + fail4; 
    EasyTracker.getTracker().sendException(sum, false); 
    } 
    catch (Exception e) 
    { 
    EasyTracker.getTracker().sendException(e.getMessage(), false); 
    } 
} 

La maggior parte delle volte rileva un'eccezione, in quanto getType o getCause è null. Questo problema si verifica sui dispositivi con versioni Android 2.1-2.3, ma ci sono alcuni rapporti dalla versione più recente come 4.0.4 o 4.2.2. Quindi non posso davvero dire che cosa ha causato il caricamento dell'immagine non riuscita

Un altro problema è IO_ERROR java.io.EOFException, che si vede soprattutto nelle versioni Android più recenti.

Il terzo degli errori più comuni sono errori out_of_memory ... Le immagini che sto tentando di caricare non sono più grandi di 1mb, ma ho bisogno di avere ScaleType.Exactly, ma durante il caricamento di immagini più grandi non sto memorizzandole nella memoria o nella cache disco, per ridurre la possibilità di out_of_memory, ma si verifica ancora abbastanza spesso.

La mia configurazione:

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(xxx.getApplicationContext()) 
.threadPoolSize(4) 
.memoryCache(new WeakMemoryCache()) 
.imageDownloader(new BaseImageDownloader(xxx.getApplicationContext(),10 * 1000, 30 * 1000)) 
.build(); 

if(!ImageLoader.getInstance().isInited()) 
           ImageLoader.getInstance().init(config); 

// options is used for images smaller in size (5kb-150kb) 
options = new DisplayImageOptions.Builder() 
.cacheInMemory() 
.cacheOnDisc() 
.showStubImage(R.drawable.stub) 
.showImageOnFail(R.drawable.failed) 
.imageScaleType(ImageScaleType.EXACTLY) 
.bitmapConfig(Bitmap.Config.RGB_565) 
.build(); 

// options2 is used for images big in size (300kb-1,2mb) 
options2 = new DisplayImageOptions.Builder() 
.showStubImage(R.drawable.stub) 
.showImageOnFail(R.drawable.failed) 
.imageScaleType(ImageScaleType.NONE) // NONE because I need to have full size bitmap loaded 
.bitmapConfig(Bitmap.Config.RGB_565) 
.build(); 

Qualcuno potrebbe dirmi come ho potuto ottimizzare il mio imageLoading per ottenere meno non è riuscito a caricare le immagini? Perché mi sento come se stessi perdendo alcuni utenti a causa di questi errori costanti nel caricare le immagini.

Aggiornamento Come ho cambiato il codice come nostra suggerito il onLoadingFailed, ora sto vedendo che tutte le relazioni che non ha .getCause() sono "DECODING_ERROR" e tutti questi sono riportati da Android 2.2-2.3.6 versioni , nessuno da quelli nuovi. Eppure gran parte dei miei utenti si trova su androidi più vecchi, qualche idea su come ridurre questo decoding_error? Ho controllato io stesso l'app su androidi più vecchi e le immagini vengono caricate quasi sempre, ma lo standard DECODING_ERROR viene riportato più spesso sull'analisi. In secondo luogo su ragioni più popolare è sempre lo stesso IO_ERROR java.io.EOFException

Update 2

personalizzata Downloader come nostra suggerito, ridotti threadPoolSize per 3 impostare un carico in più - se il caricamento non è riuscito provare a caricare di nuovo per una volta prima di dare su. Vedo che le carenze di carico diminuiscono del 30% circa. Tuttavia, si verificano ancora 100 errori di decodifica (esclusivamente per le versioni 2.2-2.3.6) e 160 errori EOF (4.0 e successivi) in 3 giorni da 500 utenti attivi quotidianamente.

Update 3

Ultima versione aggiornata ottiene molto meno errori di decodifica e EOFExceptions, credo principalmente perché cerco di caricare la stessa immagine se non riesce a caricare la prima volta. Ma .. Ora sto affrontando un altro problema: Spazio vuoto sul dispositivo java.io.IOException: write failed: ENOSPC (No space left on device). Sto usando LimitedDiscCache.

risposta

5

failReason.getType() non può essere null ma failReason.getCause() can. Dovresti controllarlo per prevenire NPE.

failReason.getCause() può essere null se si nega la rete ImageLoader.denyNetworkDownloads(true) o se si è verificato un errore di decodifica. Questo perché Android non può decodificare l'immagine per qualche motivo.

BTW Si consiglia di utilizzare .cacheOnDisc() anche per immagini grandi (options2). E magari provare un'altra implementazione della cache di memoria? Per esempio.LruMemoryCache.

Non so il motivo di java.io.EOFException ma è possibile rilevare quale rete viene utilizzata in quel momento? Mobile o WiFi? Forse prova a usare ImageLoader.handleSlowNetwork(boolean) per passare da un tipo di rete all'altro.

UPD: Prova anche a ridurre le dimensioni del pool di thread. Forse aiuta a prevenire DECODING ERRORS. UPD2: L'errore di decodifica può essere causato dal reindirizzamento del sito Web alla pagina Web. Puoi provare ad estendere BaseImageDownloader e aggiungere una stringa vuota per l'intestazione "User-Agent" nella richiesta.

public class MyImageDownloader extends BaseImageDownloader { 

private static final int MAX_REDIRECT_COUNT = 5; 

public MyImageDownloader(Context context) { 
    super(context); 
} 

protected InputStream getStreamFromNetwork(String imageUri, Object extra) throws IOException { 
    HttpURLConnection conn = connectTo(imageUri); 

    int redirectCount = 0; 
    while (conn.getResponseCode()/100 == 3 && redirectCount < MAX_REDIRECT_COUNT) { 
     conn = connectTo(conn.getHeaderField("Location")); 
     redirectCount++; 
    } 

    return new BufferedInputStream(conn.getInputStream(), BUFFER_SIZE); 
} 

protected HttpURLConnection connectTo(String url) throws IOException { 
    String encodedUrl = Uri.encode(url, ALLOWED_URI_CHARS); 
    HttpURLConnection conn = (HttpURLConnection) new URL(encodedUrl).openConnection(); 
    conn.setConnectTimeout(connectTimeout); 
    conn.setReadTimeout(readTimeout); 
    conn.setRequestProperty("User-Agent", ""); 
    return conn; 
} 
} 

O dal UIL 1.8.5:

public class MyImageDownloader extends BaseImageDownloader { 
    @Override 
    protected HttpURLConnection createConnection(String url) throws IOException { 
     HttpURLConnection conn = super.createConnection(url); 
     conn.setRequestProperty("User-Agent", ""); 
     return conn; 
    } 
} 
+0

Forse non dovrei usare affatto la memoria InMemory, per ridurre la possibilità di out_of_memory? Sto facendo del mio meglio per ridurre le dimensioni per le immagini sul lato server (comprimendo e mostrando immagini miniaturizzate), ma continuo a ottenere_della_memoria riportata nell'analisi. Io stesso non riesco a riprodurre nessuno di questi errori. Ad eccezione di EOFException, si verifica molto raramente mentre cerco di scorrere rapidamente le immagini già memorizzate nella cache e alcune di esse non riescono a caricare con EOFException. Per la connessione a Internet non posso dire esattamente, ma la maggior parte dei miei utenti non è in wifi, quindi potrebbe avere una connessione lenta – Datenshi

+0

Prova anche a ridurre le dimensioni del pool di thread. Forse aiuta a prevenire DECODING ERRORS. – NOSTRA

+0

Risposta aggiornata. UPD2 per impedire DECODING_ERROR. – NOSTRA

4

non ho mai usato Universale Caricatore immagine, ma nelle ultime settimane è stato rilasciato un paio di veramente buone alternative, potrebbero essere la pena dare un'occhiata .

Il primo è Volley, nuovo lib networking di Google ha annunciato a I/O 2013 https://developers.google.com/events/io/sessions/325304728

Il secondo è Picasso Square. Il team di Square fa un ottimo lavoro con le sue librerie Android. http://corner.squareup.com/2013/05/picasso-one-dot-oh.html

+0

Grazie, darò un'occhiata a quelli. Ma la domanda riguarda ancora Universal Image loader :) – Datenshi

Problemi correlati