2013-05-17 33 views
10

Tôi đang sử dụng trình tải hình ảnh phổ quát và tôi nhận được số lượng hình ảnh khá lớn không tải được cho người dùng mỗi ngày. Tôi đang sử dụng mã này để phát hiện lỗi của mình đối với phân tích.Trình tải ảnh phổ biến không tải được hình ảnh đôi khi

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

Phần lớn thời gian bắt ngoại lệ, như getType hoặc getCause là null. Vấn đề này được nhìn thấy trên các thiết bị với 2.1-2.3 phiên bản Android, nhưng có một số báo cáo từ phiên bản mới hơn như 4.0.4 hoặc thậm chí 4.2.2. Vì vậy, tôi thực sự không thể biết nguyên nhân khiến hình ảnh không tải được

Một vấn đề khác là IO_ERROR java.io.EOFException, chủ yếu được xem trên các phiên bản Android mới hơn. Thứ ba của các lỗi phổ biến nhất là lỗi out_of_memory ... Những hình ảnh tôi đang cố gắng tải không lớn hơn 1mb, nhưng tôi cần phải có ScaleType.Exactly, nhưng trong khi tải hình ảnh lớn hơn, tôi không lưu chúng trong bộ nhớ hoặc đĩa, để giảm khả năng out_of_memory, nhưng nó vẫn xảy ra khá thường xuyên.

cấu hình của tôi:

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

bất cứ ai có thể cho tôi biết làm thế nào tôi có thể tối ưu hóa imageLoading tôi để có được ít thất bại trong việc tải hình ảnh? Bởi vì tôi cảm thấy như tôi đang mất người dùng một số vì những thất bại liên tục để tải hình ảnh.

Cập nhật Như tôi đã thay đổi mã như nostra gợi ý trên onLoadingFailed, bây giờ tôi đang nhìn thấy rằng tất cả các báo cáo mà không có .getCause() là "DECODING_ERROR" và tất cả những được báo cáo bởi 2.2-2.3.6 phiên bản android , không có gì từ những cái mới hơn. Tuy nhiên, phần lớn người dùng của tôi vẫn đang sử dụng android cũ, bất kỳ ý tưởng nào làm giảm decoding_error này? Tôi đã tự kiểm tra ứng dụng trên Android cũ hơn và hình ảnh tải hầu hết thời gian, nhưng DECODING_ERROR được báo cáo thường xuyên nhất trên phân tích. Thứ hai về lý do phổ biến nhất vẫn là như nhau IO_ERROR java.io.EOFException

Cập nhật 2

Customized Downloader như nostra đề nghị, giảm threadPoolSize tới 3 thiết lập thêm một tải - nếu tải không cố gắng tải một lần nữa cho một thời gian trước khi đưa lên. Tôi thấy lỗi tải xuống giảm khoảng 30%. Nhưng vẫn xảy ra - 100 lỗi giải mã (chỉ dành riêng cho các phiên bản 2.2-2.3.6) và 160 lỗi EOF (4.0 trở lên) trong 3 ngày từ 500 người dùng hoạt động hàng ngày.

Cập nhật 3

phiên bản cập nhật mới nhất được lỗi giải mã ít và EOFExceptions, tôi nghĩ chủ yếu là do tôi cố gắng tải lại hình ảnh tương tự nếu nó không tải lần đầu tiên. Nhưng .. Tôi hiện đang đối mặt với một vấn đề khác: Không còn dung lượng trên thiết bị java.io.IOException: write failed: ENOSPC (No space left on device). Tôi đang sử dụng LimitedDiscCache.

Trả lời

5

failReason.getType() không được là null nhưng failReason.getCause() có thể. Bạn nên kiểm tra nó để ngăn chặn NPE.

failReason.getCause() có thể là null nếu bạn từ chối mạng bằng ImageLoader.denyNetworkDownloads(true) hoặc nếu xảy ra lỗi giải mã. Điều này là do Android không thể giải mã hình ảnh bằng một số lý do.

BTW Tôi khuyên bạn nên sử dụng .cacheOnDisc() ngay cả đối với hình ảnh lớn (options2). Và có thể thử triển khai bộ nhớ cache khác? Ví dụ.LruMemoryCache.

Tôi không biết lý do của java.io.EOFException nhưng bạn có thể phát hiện mạng nào được sử dụng trong thời gian đó không? Điện thoại di động hoặc WiFi? Có thể thử sử dụng ImageLoader.handleSlowNetwork(boolean) để chuyển đổi giữa các loại mạng.

UPD: Đồng thời cố gắng giảm kích thước nhóm của chuỗi. Có lẽ nó giúp ngăn ngừa sự phá hủy DECODING. UPD2: Lỗi giải mã có thể do trang web chuyển hướng đến trang web. Bạn có thể thử mở rộng BaseImageDownloader và thêm chuỗi trống cho tiêu đề "User-Agent" theo yêu cầu.

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

Hoặc kể từ 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

Có lẽ tôi không nên sử dụng casheInMemory, để giảm khả năng out_of_memory? Tôi đang cố hết sức để giảm kích thước cho hình ảnh ở phía máy chủ (nén và hiển thị hình ảnh thu nhỏ), nhưng tôi vẫn nhận được báo cáo out_of_memory trong phân tích. Bản thân tôi không tái tạo bất kỳ lỗi nào trong số này. Ngoại trừ EOFException, nó rất hiếm khi xảy ra trong khi tôi cố gắng vuốt nhanh qua các hình ảnh đã lưu trong bộ nhớ cache và một số trong số chúng không tải được bằng EOFException. Đối với kết nối internet tôi không thể nói chính xác, nhưng hầu hết người dùng của tôi không có trên wifi, vì vậy họ có thể có kết nối chậm – Datenshi

+0

Đồng thời cố gắng giảm kích thước nhóm của luồng. Có lẽ nó giúp ngăn ngừa việc phá hủy DECODING. – NOSTRA

+0

Đã cập nhật câu trả lời. UPD2 để ngăn DECODING_ERROR. – NOSTRA

4

Tôi chưa bao giờ sử dụng phổ Loader ảnh nhưng trong vài tuần gần đây một vài lựa chọn thay thế thực sự tốt đã được phát hành, họ có thể là đáng xem .

Đầu tiên là Volley, lib mạng mới của Google công bố tại I/O 2013 https://developers.google.com/events/io/sessions/325304728

Thứ hai là Square Picasso. Nhóm Square làm một số công việc thực sự tuyệt vời với libs Android của họ. http://corner.squareup.com/2013/05/picasso-one-dot-oh.html

+0

Cảm ơn, tôi sẽ xem xét chúng. Nhưng vẫn còn câu hỏi là về bộ nạp hình ảnh phổ quát :) – Datenshi

Các vấn đề liên quan