2013-05-17 9 views
10

Ich benutze Universal Image Loader und ich bekomme ziemlich viele Bilder, die nicht jeden Tag geladen werden können. Ich verwende diesen Code, um meine Fehler zu Analytics zu bekommen.Universal Image Loader kann Bilder manchmal nicht laden

Die meiste Zeit fängt es Ausnahme ab, wie getType, oder getCause ist null. Dieses Problem tritt auf Geräten mit 2.1-2.3 Android-Versionen auf, aber es gibt einige Berichte von neueren Versionen wie 4.0.4 oder sogar 4.2.2. So kann ich nicht wirklich sagen, was verursacht, dass das Bild nicht laden konnte

Ein anderes Problem ist IO_ERROR java.io.EOFException, das meistens auf neueren android Versionen gesehen wird.

Dritte der häufigsten Fehler sind out_of_memory Fehler ... Die Bilder, die ich laden möchte, sind nicht größer als 1mb, aber ich muss ScaleType.Exactly haben, aber während ich größere Bilder lade ich nicht im Speicher oder zwischenspeichern Disc, um die Möglichkeit von out_of_memory zu reduzieren, aber es tritt immer noch ziemlich oft auf.

Meine Konfiguration:

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(); 

Könnte mir jemand sagen, wie kann ich meinen imageLoading optimiere weniger zu bekommen scheiterten Bilder zu laden? Weil ich das Gefühl habe, dass ich einige Benutzer aufgrund dieser ständigen Fehler beim Laden von Bildern verliere.

aktualisieren Als ich den Code geändert, wie nostra auf onLoadingFailed vorgeschlagen, bin ich jetzt zu sehen, dass alle Berichte, die nicht .getCause() hat sind „DECODING_ERROR“ und all diese von android 2.2-2.3.6 Versionen berichtet Keine von neueren. Aber immer noch ein großer Teil meiner Benutzer sind auf älteren Androids, irgendeine Idee, wie man diesen decoding_error reduziert? Ich habe App selbst auf älteren Androids überprüft, und Bilder laden die meiste Zeit, aber DECODING_ERROR wird am häufigsten über Analytics gemeldet. Zweitens auf dem beliebtestenen Gründen ist immer noch der gleiche IO_ERROR java.io.EOFException

Update 2

Customized Downloader als nostra vorgeschlagen, reduziert threadPoolSize bis 3 eine zusätzliche Belastung einrichten - wenn Laden versucht, scheitert erneut für eine Zeit zu laden, bevor er oben. Ich sehe Mängel beim Laden um etwa 30% verringert. Aber immer noch auftreten - 100 Decodierungsfehler (ausschließlich nur auf 2.2-2.3.6 Versionen) und 160 EOF Fehler (4.0 und höher) in 3 Tagen von 500 täglich aktiven Benutzern.

Update 3

Neueste aktualisierte Version weit weniger Dekodierfehlern und EOFExceptions wird, denke ich, vor allem, weil ich versuche, das gleiche Bild neu zu laden, wenn es das erste Mal geladen werden kann. Aber .. Ich bin jetzt ein anderes Problem: Kein Platz mehr auf dem Gerät java.io.IOException: write failed: ENOSPC (No space left on device). Ich verwende LimitedDiscCache.

Antwort

5

failReason.getType() kann nicht null aber failReason.getCause() kann. Sie sollten dies überprüfen, um NPE zu verhindern.

failReason.getCause() kann null sein, wenn Sie Netzwerk durch ImageLoader.denyNetworkDownloads(true) verweigern oder wenn Decodierungsfehler aufgetreten ist. Dies liegt daran, dass Android das Bild aus irgendeinem Grund nicht dekodieren kann.

BTW Ich empfehle Ihnen, .cacheOnDisc() auch für große Bilder zu verwenden (options2). Und vielleicht andere Speicher Cache-Implementierung versuchen? Z.B.LruMemoryCache.

Ich kenne nicht den Grund von java.io.EOFException, aber können Sie erkennen, welches Netzwerk in dieser Zeit verwendet wird? Mobil oder WiFi? Versuchen Sie vielleicht, ImageLoader.handleSlowNetwork(boolean) zu verwenden, um zwischen Netzwerktypen zu wechseln.

UPD: Versuchen Sie auch, Thread-Pool-Größe zu reduzieren. Vielleicht hilft es, DECODING ERRORS zu verhindern. UPD2: Der Decodierungsfehler kann durch eine Umleitung der Website auf die Webseite verursacht werden. Sie können versuchen, erweitern BaseImageDownloader und fügen Sie leere Zeichenfolge für "User-Agent" Header in der Anfrage.

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; 
} 
} 

Oder seit 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

Vielleicht sollte ich CasheInMemory überhaupt nicht verwenden, um die Möglichkeit von out_of_memory zu reduzieren? Ich tue mein Bestes, um die Größe für Bilder auf der Serverseite zu reduzieren (komprimierte und angezeigte thumbnailed Bilder), aber ich bekomme immer noch out_of_memory in Analytics gemeldet. Ich selbst kann keine dieser Fehler reproduzieren. Abgesehen von EOFException tritt es sehr selten auf, während ich versuche, bereits zwischengespeicherte Bilder schnell durchzuwischen, und einige von ihnen können nicht mit EOFException geladen werden. Für die Internetverbindung kann ich nicht genau sagen, aber die meisten meiner Benutzer sind nicht auf Wifi, so dass sie langsam Verbindung haben können – Datenshi

+0

Auch versuchen, Thread-Pool-Größe zu reduzieren. Vielleicht hilft es, DECODING ERRORS zu verhindern. – NOSTRA

+0

Aktualisierte Antwort. UPD2, um DECODING_ERROR zu verhindern. – NOSTRA

4

ich nie Universal-Image Loader verwendet haben, aber in den letzten Wochen ein paar wirklich gute Alternativen veröffentlicht wurden, könnten sie wert sein, einen Blick .

Die erste ist, Volley, neue Netzwerk lib an I/O kündigte Google 2013 https://developers.google.com/events/io/sessions/325304728

Die zweite ist Picassos Platz. Das Square-Team macht mit seinen Android-Bibliotheken sehr gute Arbeit. http://corner.squareup.com/2013/05/picasso-one-dot-oh.html

+0

Danke, ich werde mir die ansehen. Aber immer noch ist die Frage über Universal Image Loader :) – Datenshi

Verwandte Themen