Load ảnh trong Android với Universal Image Loader
Bài đăng này đã không được cập nhật trong 3 năm
1. Giới thiệu
Universal Image Loader là một thư viện mã nguồn mở, mục đích xây dựng là để cung cấp một công cụ mạnh mẽ, linh hoạt và có tính tùy biến cao cho việc load, cache và hiển thị ảnh. Nó cung cấp rất nhiều những tùy chọn cấu hình và có khả năng control tốt trong quá trình tải và cache ảnh.
Hiện tại, Universal Image Loader ngưng đc phát triển thêm từ tháng 11/2015 do tác giả k có thời gian. Tuy nhiên, là 1 thư viện mã nguồn mở, bạn hoàn toàn có thể fork project và tự phát triển thêm cho riêng mình hoặc cho cộng đồng android developer.
2. Các tính năng
- Load ảnh đa luồng (đồng bộ và bất đồng bộ)
- Khả năng tùy biến cao (các tùy chọn cho viện thực thi đa luồng, tải ảnh, giải mã, cache bộ nhớ, hiển thị v.v.v.).
- Cache ảnh trong bộ nhớ hoặc/và trên ổ đĩa
- Theo dõi quá trình load ảnh (bao gồm quá trình download ảnh)
3. Tải xuống
universal-image-loader-1.9.5.jar
Github repo : https://github.com/nostra13/Android-Universal-Image-Loader
4. Hướng dẫn sử dụng
Một số mẫu URI có thể sử dụng:
"http://site.com/image.png" // từ trên mạng
"file:///mnt/sdcard/image.png" // từ SD card
"file:///mnt/sdcard/video.mp4" // từ SD card (video thumbnail)
"content://media/external/images/media/13" // từ content provider
"content://media/external/video/media/13" // từ content provider (video thumbnail)
"assets://image.png" // từ assets
"drawable://" + R.drawable.img // từ drawables (không bao gồm ảnh 9patch)
CHÚ Ý Sử dụng "drawable://" chỉ khi thực sự cần nó. Luôn cân nhắc sử dụng ImageView.setImageResource(...) thay vì sử dụng cho việc load drawable
Khởi tạo đối tượng
ImageLoader imageLoader = ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(context));
Ở trên ta đã khởi tạo đối tượng ImageLoader vói cấu hình tùy chọn mặc định. Bạn có thể thay đổi những tùy chọn cho riêng mình giống như ví dụ ở phần 5
Load ảnh, giải mã nó thành bitmap và hiển thị bitmap lên ImageView (hay bất cứ lớp view nào implement interface ImageAware
imageLoader.displayImage(imageUri, imageView);
Bạn cũng có thể load ảnh, giải mã nó thành bitmap và thực hiện bất cứ điều gì bạn muốn ở từng sự kiện tuơng ứng trong quá trình xử lý nó, hay theo dõi quá trình load ảnh như dưới đây.
// Load image, decode it to Bitmap and display Bitmap in ImageView (or any other view
// which implements ImageAware interface)
imageLoader.displayImage(imageUri, imageView, options, new ImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
...
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
...
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
...
}
@Override
public void onLoadingCancelled(String imageUri, View view) {
...
}
}, new ImageLoadingProgressListener() {
@Override
public void onProgressUpdate(String imageUri, View view, int current, int total) {
...
}
});
Hoặc đơn giản hơn, ta có thể sử dụng SimpleImageLoadingListener thay vì ImageLoadingListener nếu như không muốn bị buộc phải cài đè 4 phuơng thức trên (cài đề nếu bạn muốn)
imageLoader.loadImage(url, new SimpleImageLoadingListener(){
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
Toast.makeText(mContext, "Đã load xong", Toast.LENGTH_SHORT).show();
imageView.setImageBitmap(loadedImage);
}
});
Bạn cũng có thể load ảnh, giải mã ảnh để nhận về bitmap 1 cách đồng bộ bằng cách sử dụng hàm loadImageSync(Uri uri)
Bitmap bmp = imageLoader.loadImageSync(imageUri);
Bạn cũng có thể thêm tùy chọn về kích cỡ của ảnh nếu muốn như sau
// Load image, decode it to Bitmap and return Bitmap to callback
ImageSize targetSize = new ImageSize(80, 50); // result Bitmap will be fit to this size
imageLoader.loadImage(imageUri, targetSize, options, new SimpleImageLoadingListener() {
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// Do whatever you want with Bitmap
}
});
Hoặc dùng cách dưới đây mà không thiết kế bất cứ gì cho từ ảnh
// Load image, decode it to Bitmap and return Bitmap synchronously
ImageSize targetSize = new ImageSize(80, 50); // result Bitmap will be fit to this size
Bitmap bmp = imageLoader.loadImageSync(imageUri, targetSize, options);
5. Luồng xử lý
Luồng xử lý đc thể hiện rất rõ trên hình nên mình sẽ không mô tả chỉ tiết. Nhưng ta có thể thấy nó trải qua 7 giai đoạn đối với một ảnh mới hoàn toàn bao gồm
- Tải ảnh
- Cache ảnh lên đĩa nhớ
- Giải mã ảnh thành bitmap
- Tiền xử lý bitmap
- Lưu bitmap đã được xử lý vào bộ nhớ
- Hậu xử lý
- Hiển thị ảnh
Đối với ảnh không mới (đã được luư trên bộ nhớ hoặc đĩa nhớ), một số giai đoạn đầu sẽ bị lược bỏ (do thực tế đã được thực hiện trứoc đó) như hình phía trên.
6. Ví dụ
Dưới đây là 1 ví dụ cho việc sử dụng Universal Image Loader
import android.app.Application;
import com.nostra13.universalimageloader.cache.memory.impl.WeakMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
String url = "http://img.blogtamsu.vn/2015/11/ngoc-trinh-blogtamsuvn-38.jpg";
// Cấu hình tùy chọn hiển thị ảnh
DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.cacheOnDisc(true).cacheInMemory(true)
.imageScaleType(ImageScaleType.EXACTLY)
.displayer(new FadeInBitmapDisplayer(300)).build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
getApplicationContext())
.defaultDisplayImageOptions(defaultOptions)
.memoryCache(new WeakMemoryCache())
.discCacheSize(100 * 1024 * 1024).build();
// Khởi tại đối tượng imageLoader với cấu hình ta đã set vên trên
// bạn cũng có thể sử dụng config mặc định bằng cách
// imageLoader.init(ImageLoaderConfiguration.createDefault(mContext));
ImageLoader imageLoader = ImageLoader.getInstance().init(config);
ImageView imageView = (ImageView) findViewById(R.id.imageView1)
//download ảnh và show ImageView tại đây
imageLoader.displayImage(url, imageView, options);
}
}
Còn do dự gì nữa? Hãy tạo một project và thử ngay Universal Image Loader để hiểu hơn về cách nó hoạt động. Chúc các bạn vui vẻ.
All rights reserved