2013-05-17 8 views
10

私はユニバーサル画像ローダーを使用しており、毎日たくさんの画像を読み込むことができません。 私はこのコードを使用して、分析にエラーを出しています。ユニバーサル画像ローダーが画像を読み込めない場合があります

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

ほとんどの場合、getTypeまたはgetCauseがnullであるため、例外をキャッチします。この問題は2.1-2.3アンドロイドバージョンのデバイスで見られますが、4.0.4や4.2.2などの新しいバージョンのレポートがあります。だから私は実際に画像の読み込みに失敗した原因を知ることができません

もう1つの問題は、ほとんどの新しいアンドロイドバージョンで見られるIO_ERROR java.io.EOFExceptionです。

最も一般的なエラーの3番目はout_of_memory errorsです...私がロードしようとしている画像は1MB以下ですが、ScaleType.Exactlyが必要ですが、大きな画像をロードする際にはメモリにキャッシュしません。 out_of_memoryの可能性を減らすために、しかしそれはまだかなり頻繁に起こります。

マイ設定:

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

誰がどのように私は画像を読み込むことができませんでしたあまりを得るために、私imageLoadingを最適化する可能性を教えてもらえますか?なぜなら、画像をロードするこれらの不断の失敗のために私はいくつかのユーザーを失っているように感じるからです。

更新 ノストラは、私が今.getCause()を持っていないすべてのレポートは、「DECODING_ERROR」であり、これらすべてがアンドロイド2.2-2.3.6のバージョンによって報告されていることを見ているonLoadingFailedで示唆したように、私は、コードを変更したようより新しいものはありません。しかし、私のユーザーの大部分は古いAndroidの上にあります。どのようにすればこのデコードエラーを減らすことができますか?私は年配のアンドロイドで自分でアプリをチェックしていましたが、ほとんどの場合イメージに負荷がかかるのですが、DECODING_ERRORがアナリティクスで最も多く報告されています。第二にカスタマイズDownloaderのアップデート2まだ同じIO_ERROR java.io.EOFException

ある

最も人気の理由のノストラが示唆したように、余分な荷重を設定3にthreadPoolSizeを削減 - ロードを与える前に1時間のために再ロードしようと失敗した場合アップ。私は負荷の失敗が約30%減少したのを見る。しかし、毎日500人のアクティブユーザーから3日間で100のデコードエラー(2.2-2.3.6バージョンのみ)と160のEOFエラー(4.0以上)が発生します。

アップデート3

最新の更新されたバージョンがはるかに少ないデコードエラーとEOFExceptionsを取得し、私はそれが初めてのロードに失敗した場合、同じ画像をリロードしようとするので、私は主だと思います。しかし、私は今、別の問題に直面しています:デバイス上にスペースが残っていませんjava.io.IOException: write failed: ENOSPC (No space left on device)。私はLimitedDiscCacheを使用しています。

答えて

5

failReason.getType()は、nullではなく、failReason.getCause()であることができる。 NPEを防ぐためにチェックする必要があります。

failReason.getCause()ImageLoader.denyNetworkDownloads(true)でネットワークを拒否した場合、またはデコードエラーが発生した場合は、nullになります。これは、何らかの理由でAndroidが画像をデコードできないためです。

私は大きな画像(options2)でも.cacheOnDisc()を使用することをお勧めします。 おそらく他のメモリキャッシュの実装を試してみませんか?例えば。LruMemoryCache

私はjava.io.EOFExceptionの理由を知りませんが、その時間にどのネットワークが使用されているか検出できますか?モバイルかWiFi?おそらくImageLoader.handleSlowNetwork(boolean)を使ってネットワークタイプを切り替えることを試みてください。

UPD:また、スレッドプールサイズを縮小しようとします。 DECODING ERRORSを防ぐのに役立つかもしれません。 UPD2:デコードエラーは、WebサイトがWebページにリダイレクトすることによって発生する可能性があります。 BaseImageDownloaderを拡張して、リクエストに「User-Agent」ヘッダーの空の文字列を追加してみてください。

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

または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

out_of_memoryの可能性を減らすために、私はcasheInMemoryを使用しないでください。私はサーバ側の画像のサイズを縮小するために最善を尽くしていますが(サムネイル画像を圧縮して表示しています)、解析結果でout_of_memoryが表示されます。私はこれらのエラーを再現することはできません。 EOFExceptionを除いて、すでにキャッシュされたイメージをすばやくスワイプしようとする間に非常にめったに発生せず、そのうちのいくつかはEOFExceptionで読み込まれません。インターネット接続の場合、正確にはわかりませんが、ほとんどのユーザーは無線LANに接続されていないため、接続が遅い可能性があります。 – Datenshi

+0

スレッドプールのサイズを縮小しようとします。 DECODING ERRORSを防ぐのに役立つかもしれません。 – NOSTRA

+0

更新された回答。 DECODING_ERRORを防ぐためにUPD2。 – NOSTRA

4

私はユニバーサルイメージ・ローダーを使用したことがないが、最後の数週間で本当に良い選択肢のカップルがリリースされている、彼らは一見の価値があるかもしれません。

最初は、第二は、スクエアのピカソでバレーボール、I/O 2013 https://developers.google.com/events/io/sessions/325304728

で発表されたGoogleの新しいネットワーキングlibです。スクエアチームは、Androidライブラリで本当に素晴らしい仕事をしています。 http://corner.squareup.com/2013/05/picasso-one-dot-oh.html

+0

ありがとう、私はそれらを見てみましょう。しかし、まだ質問はユニバーサルイメージローダーについてです:) – Datenshi

関連する問題