Giải pháp bộ nhớ đệm hình ảnh cục bộ cho Android: Square Picasso, Universal Image Loader, Glide, Fresco?


89

Tôi đang tìm kiếm thư viện lưu và tải hình ảnh không đồng bộ trong Android. Tôi định sử dụng Picasso, nhưng tôi thấy Universal Image Loader phổ biến hơn trên GitHub. Có ai biết về hai thư viện này không? Một bản tóm tắt về ưu và nhược điểm sẽ rất tuyệt.

(Tất cả hình ảnh của tôi đều nằm trên đĩa cục bộ, vì vậy tôi không cần kết nối mạng, do đó tôi không nghĩ Volley phù hợp)

Câu trả lời:


80

Cập nhật tháng 9 năm 2018: Sau vài năm, tôi cần thứ gần như tương tự cho giải pháp bộ nhớ đệm hình ảnh cục bộ. Khoảng thời gian này, UIL vẫn chưa được phát triển tích cực. Tôi đã so sánh các thư viện phổ biến, và kết luận khá dễ hiểu: chỉ cần sử dụng Glide. Nó mạnh hơn nhiều và có thể cấu hình. Nhiều năm trước, tôi đã phải fork và thực hiện các thay đổi đối với UIL. Glide hỗ trợ tất cả các trường hợp sử dụng của tôi về chiến lược bộ nhớ đệm và nhiều cấp độ phân giải bộ nhớ đệm với các phím tùy chỉnh. Chỉ cần sử dụng Glide!

So sánh của Koushik Dutta chủ yếu là để chuẩn tốc độ. Bài đăng của anh ấy chỉ đề cập đến những điều rất cơ bản, và không cụ thể cho hình ảnh địa phương. Tôi muốn chia sẻ kinh nghiệm của mình với Picasso và UIL sau khi tôi đặt câu hỏi. Cả Picasso và UIL đều có thể tải hình ảnh cục bộ. Lần đầu tiên tôi dùng thử Picasso và rất vui, nhưng sau đó tôi quyết định chuyển sang UIL để có nhiều tùy chọn tùy chỉnh hơn.

Picasso:

  • Giao diện thông thạo của Picasso rất đẹp. Nhưng nhảy xung quanh với "với", "thành", "tải" bạn thực sự không biết những gì đằng sau cảnh. Thật khó hiểu những gì được trả lại.

  • Picasso cho phép bạn chỉ định kích thước mục tiêu chính xác. Nó hữu ích khi bạn gặp vấn đề về áp lực bộ nhớ hoặc hiệu suất, bạn có thể đánh đổi một số chất lượng hình ảnh để lấy tốc độ.

  • Hình ảnh được lưu vào bộ nhớ đệm với kích thước trong khóa của nó, rất hữu ích khi bạn hiển thị hình ảnh với các kích thước khác nhau.

  • Bạn có thể tùy chỉnh kích thước bộ nhớ đệm. Nhưng bộ đệm đĩa của nó chỉ dành cho các yêu cầu http. Đối với hình ảnh cục bộ, nếu bạn quan tâm đến tốc độ tải, thì tốt nhất là bạn nên có một bộ đệm đĩa hình thu nhỏ để bạn không phải đọc vài MB cho một hình ảnh mỗi lần. Picasso không có cơ chế này để thay đổi kích thước và lưu hình thu nhỏ trên đĩa.

  • Picasso không để lộ quyền truy cập vào phiên bản bộ nhớ cache của nó. (Bạn có thể nắm giữ nó khi bạn định cấu hình Picasso lần đầu tiên và giữ nó xung quanh ...).

  • Đôi khi bạn muốn đọc một cách không đồng bộ hình ảnh thành một bitmap do người nghe trả về. Đáng ngạc nhiên là Picasso không có điều đó. Liều "fetch ()" không trả lại bất kỳ thứ gì. "get ()" là để đọc đồng bộ và "load ()" là để vẽ một chế độ xem không đồng bộ.

  • Picasso chỉ có một số ví dụ đơn giản trên trang chủ và bạn sẽ phải đọc qua javadoc không có thứ tự để biết các cách sử dụng nâng cao.

UIL:

  • UIL sử dụng trình xây dựng để tùy chỉnh. Hầu hết mọi thứ đều có thể được cấu hình.

  • UIL không cho phép bạn chỉ định kích thước bạn muốn tải vào một dạng xem. Nó sử dụng một số quy tắc dựa trên kích thước của khung nhìn. Nó không linh hoạt như Picasso. Tôi không có cách nào để tải hình ảnh có độ phân giải thấp hơn để giảm dung lượng bộ nhớ. (Chỉnh sửa: hành vi này có thể được sửa đổi dễ dàng bằng cách thêm đối số ImageSize trong mã nguồn và bỏ qua kiểm tra kích thước chế độ xem)

  • UIL cung cấp bộ đệm đĩa có thể tùy chỉnh, bạn có thể sử dụng bộ đệm này để lưu vào bộ đệm các hình thu nhỏ với kích thước được chỉ định. Nhưng nó không hoàn hảo. Đây là chi tiết . (Chỉnh sửa: nếu bạn quan tâm đến tốc độ và muốn có nhiều cấp độ bộ nhớ đệm hình thu nhỏ, giống như trường hợp của tôi, bạn có thể sửa đổi mã nguồn, để bộ nhớ cache trên đĩa sử dụng "memoryKey" và làm cho nó cũng có kích thước nhạy cảm)

  • UIL theo mặc định lưu trữ các hình ảnh có kích thước khác nhau trong bộ nhớ và có thể tắt nó trong cấu hình.

  • UIL để lộ bộ nhớ sao lưu và bộ đệm đĩa mà bạn có thể truy cập.

  • UIL cung cấp các cách linh hoạt để bạn có thể tải bitmap hoặc tải vào một chế độ xem.

  • UIL tốt hơn trong tài liệu. UIL cung cấp cách sử dụng chi tiết trên trang Github và có một hướng dẫn được liên kết.

Tôi khuyên bạn nên bắt đầu với Picasso, nếu bạn cần kiểm soát và tùy chỉnh nhiều hơn, hãy sử dụng UIL.


Tôi thực sự bị mắc kẹt giữa cả hai ... Về cơ bản, tôi sẽ khôi phục hình ảnh từ máy chủ của mình được lưu trữ trong một thư mục ở đó ... vì vậy thông qua các cuộc gọi http và sau đó lưu trữ nó vào bộ nhớ đệm (hình thu nhỏ và kích thước thông thường, tôi có thể sẽ lưu trữ cả hai kích thước trên thư mục của tôi) ... picasso là cách để đi sau đó?
Lion789

@ Lion789 Picasso chỉ thực hiện bộ nhớ cache cục bộ cho các tệp cục bộ và nó sử dụng HttpResponseCache cho bộ nhớ đệm đĩa mạng, bạn phải xem xét điều đó. UIL có bộ đệm đĩa có thể định cấu hình, bạn có thể thực hiện một số thay đổi nhỏ để cho phép nó chấp nhận kích thước hình ảnh / hình thu nhỏ khác nhau. Có thể thử Picasso trước, nếu bạn thấy nó quá hạn chế, hãy chuyển sang UIL và tùy chỉnh
XY

Vì vậy, Picasso có thể tải hình ảnh nhỏ hơn! Sau đó, tôi không phải tải những cái 8 megapixel! Cảm ơn, bạn đã giúp tôi!
Aron Lorincz

Bạn có thể vui lòng trả lời câu hỏi này? stackoverflow.com/questions/35433895/…
Usman Rana

UIL does not allow you to specify the size you want to load into a viewkhông phải là 100% đúng .. với UIL bạn có thể sử dụngpublic void displayImage(String uri, ImageAware imageAware, DisplayImageOptions options, ImageSize targetSize, ImageLoadingListener listener, ImageLoadingProgressListener progressListener)
Martin Mlostek

72

Nếu bạn đọc bài đăng này trên G + của Koush, bạn sẽ nhận được giải pháp rõ ràng cho sự nhầm lẫn của mình, tôi đã đưa ra tóm tắt về điều đó, trong đó Android-Universal-Image-Loader là người chiến thắng cho yêu cầu của bạn!

  • Picasso có API hình ảnh đẹp nhất nếu bạn đang sử dụng mạng!

  • UrlImageViewHelper + AndroidAsync là nhanh nhất. Tuy nhiên, chơi với hai thư viện tuyệt vời khác này đã thực sự làm nổi bật rằng API hình ảnh đã khá cũ.

  • Vô-lê là bóng mượt; Tôi thực sự thích thú với việc vận chuyển phụ trợ có thể cắm được của họ
    và có thể cuối cùng sẽ bỏ AndroidAsync vào đó. Ưu tiên yêu cầu
    và quản lý hủy bỏ là rất tốt (nếu bạn đang sử dụng mạng)

  • Android-Universal-Image-Loader là ứng dụng phổ biến nhất
    hiện nay. Khả năng tùy biến cao.

Dự án này nhằm cung cấp một công cụ có thể tái sử dụng để tải, lưu vào bộ nhớ đệm và hiển thị hình ảnh không đồng bộ. Ban đầu nó dựa trên dự án của Fedor Vlasov và đã được tái cấu trúc và cải tiến rất nhiều kể từ đó.

Những thay đổi sắp tới trong phiên bản UIL mới (1.9.2):

Khả năng gọi ImageLoader ra khỏi chuỗi giao diện người dùng API bộ nhớ đệm đĩa mới (linh hoạt hơn). LruDiscCache mới dựa trên DiskLruCache của Jake Wharton.

Xem xét tất cả các bộ Android-Universal-Image-Loader này theo yêu cầu của bạn ( Tải hình ảnh trên đĩa cục bộ )!


Tôi bắt đầu với Picasso và kết thúc chuyển sang Universal, mặc dù mọi thứ đã được triển khai đầy đủ. Picasso có giao diện api tốt hơn nhưng cũng có nhiều vấn đề. Đây là chiếc đinh cuối cùng trong quan tài.
Lisandro

45

Tôi muốn chia sẻ kinh nghiệm của mình với 3 thư viện này: UIL, Picasso và Volley. Trước đây tôi đã sử dụng UIL nhưng sau đó tôi đi đến kết luận rằng tôi không thể thực sự đề xuất nó và tôi sẽ đề xuất sử dụng Volley hoặc Picasso để thay thế, cả hai đều được phát triển bởi các nhóm tài năng cao. UIL không tệ chút nào nhưng nó thiếu sự chú ý đến từng chi tiết của hai thư viện còn lại.

Tôi thấy UIL kém đẹp hơn với hiệu suất giao diện người dùng; nó có xu hướng khóa chuỗi giao diện người dùng hơn Volley hoặc Picasso. Điều này có thể một phần là do UIL không hỗ trợ phân phối các phản hồi hình ảnh trong khi Picasso và Volley làm điều đó theo mặc định.

Ngoài ra, tôi không thích hệ thống bộ đệm đĩa của UIL. Trong khi bạn có thể chọn giữa các cách triển khai khác nhau, tôi cần chỉ ra rằng hiện tại không có cách nào để giới hạn bộ nhớ cache của đĩa UIL cả theo tổng kích thước và thời gian hết hạn của thực thể. Volley và Picasso làm điều đó và họ sử dụng thời gian hết hạn do máy chủ trả về theo mặc định trong khi UIL bỏ qua nó.

Cuối cùng, UIL cho phép bạn thiết lập cấu hình bộ tải hình ảnh chung bao gồm cài đặt và triển khai bộ đệm ẩn đĩa và bộ nhớ đệm đã chọn và các chi tiết khác, nhưng cấu hình này sẽ được áp dụng ở mọi nơi trong ứng dụng của bạn. Vì vậy, nếu bạn cần sự linh hoạt hơn như hai bộ đệm đĩa riêng biệt, thì không nên dùng UIL. Mặt khác, Volley cho phép bạn có nhiều bộ tải hình ảnh riêng biệt tùy thích, mỗi bộ có cấu hình riêng. Picasso sử dụng một phiên bản chung theo mặc định nhưng cũng cho phép bạn tạo các phiên bản có thể định cấu hình riêng biệt.

Tóm lại: Picasso có API tốt nhất nhưng nó sử dụng bộ đệm ẩn đĩa HTTP toàn cầu được chia sẻ giữa tất cả các HttpURLConnectiontrường hợp, điều này có thể quá hạn chế trong một số trường hợp. Volley có hiệu suất và tính mô-đun tốt nhất nhưng ít thân thiện với người dùng hơn và sẽ yêu cầu bạn viết một hoặc hai mô-đun của riêng bạn để làm cho nó hoạt động như bạn muốn. Nhìn chung, tôi muốn giới thiệu cả hai chống lại UIL.

Chỉnh sửa (18 tháng 12 năm 2014): Mọi thứ đã thay đổi kể từ khi tôi viết câu trả lời đầu tiên này và tôi cảm thấy cần phải cải thiện nó:

Picasso 2.4 thậm chí còn có thể định cấu hình tốt hơn so với các phiên bản cũ và khi được sử dụng với OkHttp (rất được khuyến khích), nó cũng có thể sử dụng bộ đệm đĩa riêng biệt cho từng phiên bản nên thực sự không có hạn chế về những gì bạn có thể làm. Quan trọng hơn, tôi nhận thấy rằng hiệu suất của Picasso và OkHttp đã được cải thiện rất nhiều và theo ý kiến ​​của tôi, nó hiện là giải pháp tải hình ảnh nhanh nhất cho Android. Xin lưu ý rằng trong mã của tôi, tôi luôn sử dụng .fit()kết hợp với .centerCrop()hoặc .centerInside()để giảm mức sử dụng bộ nhớ và tránh thay đổi kích thước bitmap trên chuỗi giao diện người dùng. Picasso được phát triển và hỗ trợ tích cực và đó chắc chắn là một điểm cộng lớn.

Volley không thay đổi nhiều nhưng tôi nhận thấy hai vấn đề với nó trong thời gian chờ đợi:

  • Đôi khi dưới tải nặng, một số hình ảnh không được tải nữa do một số lỗi bộ nhớ đệm ổ đĩa.
  • Hình thu nhỏ hiển thị trong NetworkImageView (với loại tỷ lệ được đặt thành centerCrop) khá mờ so với những gì bạn nhận được với các thư viện khác.

Vì những lý do này, tôi quyết định ngừng sử dụng Volley.

UIL vẫn còn chậm (đặc biệt là bộ nhớ cache trên đĩa) và API của nó có xu hướng thay đổi khá thường xuyên.

Tôi cũng đã thử nghiệm thư viện mới này có tên là Glide 3 , được tuyên bố là tối ưu hóa hơn Picasso với API giống Picasso. Theo kinh nghiệm cá nhân của tôi, nó thực sự chậm hơn Picasso và Volley khi yêu cầu mạng dưới tải nặng, ngay cả khi được sử dụng kết hợp với OkHttp. Tệ hơn nữa, nó gây ra một số lỗi với các ứng dụng của tôi trong Lollipop khi rời khỏi một hoạt động. Nó vẫn có 2 lợi thế so với các đối thủ cạnh tranh:

  • Nó hỗ trợ giải mã GIF động
  • Nó đặt các bitmap được giảm tỷ lệ cuối cùng vào bộ nhớ cache của đĩa, có nghĩa là việc đọc lại từ bộ nhớ cache của đĩa là cực kỳ nhanh.

Kết luận: Bây giờ tôi khuyên bạn nên sử dụng Picasso + OkHttp vì nó cung cấp kết hợp tính linh hoạt, API, hiệu suất và độ ổn định tốt nhất. Nếu bạn cần hỗ trợ GIF, bạn cũng có thể xem xét Glide.


1
Để giải quyết điểm cuối cùng của bạn trên UIL, bạn có thể tạo nhiều ImageLoaderlớp và cấu hình khác nhau tùy thích. Bạn chỉ cần phân lớp con của ImageLoaderlớp. Xem tại đây: github.com/nostra13/Android-Universal-Image-Loader/issues/…
TalkLittle Ngày

Trông giống như một hack nhưng cảm ơn bạn vì mẹo, rất tốt để biết.
BladeCoder

3
Không thể nói rằng tôi đồng ý với ý kiến ​​đó, chúng tôi sử dụng Picasso ở đây, tôi có một album với hơn 500 hình ảnh độ phân giải cao, và tôi đang gặp vấn đề về hiệu suất và bộ nhớ, đã thử UIL và mọi thứ đã được giải quyết ngay lập tức. Đây là một mẫu tối thiểu giúp tách biệt các vấn đề của chúng tôi mà chúng tôi đang thấy.
HaMMeReD

Nếu bạn đang hiển thị hình ảnh có độ phân giải cao hơn nhiều so với màn hình hoặc nhiều hình thu nhỏ của hình ảnh có độ phân giải cao, bạn chắc chắn nên giảm mẫu chúng xuống. Tôi nghĩ UIL thực hiện điều này tự động và Picasso thì không nếu bạn không chỉ định các tùy chọn thích hợp, do đó các vấn đề về bộ nhớ. Cá nhân tôi thích sử dụng NetworkImageView trong Volley, đó là một tiện ích giúp giảm hình ảnh được tải xuống kích thước của chính nó.
BladeCoder

Trong UIL, Lớp DisplayImageOptions có thể được sử dụng nếu chúng ta không muốn thay đổi hoặc áp dụng một số xử lý khác trên một hình ảnh cụ thể.
Rahul Rastogi

7

Tôi đã triển khai một ứng dụng liên tục lấy và hiển thị hình ảnh từ internet. Tôi chuẩn bị lập trình một cơ chế bộ nhớ cache hình ảnh, trước đó một người bạn đã giới thiệu cho tôi trình tải hình ảnh đa năng.

UIL có thể tùy chỉnh rất tốt. Nó có thể tùy chỉnh đến mức một người mới có thể dễ dàng mắc sai lầm. Tuy nhiên, UIL chậm trong ứng dụng của tôi và nó trở nên chậm hơn một chút. Trường hợp sử dụng của tôi là một ListView có hình ảnh.

Hôm qua, tôi đang tìm kiếm một giải pháp thay thế cho UIL và tôi đã phát hiện ra Picasso. Picasso rất dễ tích hợp và sử dụng: Chỉ cần Picasso.context(context).load(url).into(imageview)và hình ảnh có thể được tích hợp nhanh hơn và trơn tru.

Đối với tôi, Picasso chắc chắn là API để sử dụng. Trải nghiệm của tôi với UIL không tốt.


Đối với độc giả tương lai: Tốt hơn picasso là Glide. Hãy xem
therealprashant

0

Tôi nghĩ ImageLoader có thể tùy chỉnh và linh hoạt hơn so với thư viện Picasso.


8
Làm sao? một chút giải thích sẽ hữu ích.
Darpan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.