package com.netease.nim.uikit;
import android.content.Context;
import android.graphics.Bitmap;
import android.text.TextUtils;
import com.netease.nim.uikit.common.media.picker.util.BitmapUtil;
import com.netease.nim.uikit.common.ui.imageview.HeadImageView;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nimlib.sdk.uinfo.UserInfoProvider;
import com.nostra13.universalimageloader.cache.disc.impl.ext.LruDiskCache;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageSize;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
import com.nostra13.universalimageloader.core.download.ImageDownloader;
import com.nostra13.universalimageloader.utils.MemoryCacheUtils;
import com.nostra13.universalimageloader.utils.StorageUtils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* 图片加载、缓存、管理组件
*/
public class ImageLoaderKit {
private static final String TAG = ImageLoaderKit.class.getSimpleName();
private static final int M = 1024 * 1024;
private Context context;
private static List<String> uriSchemes;
public ImageLoaderKit(Context context, ImageLoaderConfiguration config) {
this.context = context;
init(config);
}
private void init(ImageLoaderConfiguration config) {
try {
ImageLoader.getInstance().init(config == null ? getDefaultConfig() : config);
} catch (IOException e) {
LogUtil.e(TAG, "init ImageLoaderKit error, e=" + e.getMessage().toString());
}
LogUtil.i(TAG, "init ImageLoaderKit completed");
}
public void clear() {
ImageLoader.getInstance().clearMemoryCache();
}
private ImageLoaderConfiguration getDefaultConfig() throws IOException {
int MAX_CACHE_MEMORY_SIZE = (int) (Runtime.getRuntime().maxMemory() / 8);
File cacheDir = StorageUtils.getOwnCacheDirectory(context, context.getPackageName() + "/cache/image/");
LogUtil.i(TAG, "ImageLoader memory cache size = " + MAX_CACHE_MEMORY_SIZE / M + "M");
LogUtil.i(TAG, "ImageLoader disk cache directory = " + cacheDir.getAbsolutePath());
ImageLoaderConfiguration config = new ImageLoaderConfiguration
.Builder(context)
.threadPoolSize(3) // 线程池内加载的数量
.threadPriority(Thread.NORM_PRIORITY - 2) // 降低线程的优先级,减小对UI主线程的影响
.denyCacheImageMultipleSizesInMemory()
.memoryCache(new LruMemoryCache(MAX_CACHE_MEMORY_SIZE))
.discCache(new LruDiskCache(cacheDir, new Md5FileNameGenerator(), 0))
.defaultDisplayImageOptions(DisplayImageOptions.createSimple())
.imageDownloader(new BaseImageDownloader(context, 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超时时间
.writeDebugLogs()
.build();
return config;
}
/**
* 判断图片地址是否合法,合法地址如下:
* String uri = "http://site.com/image.png"; // from Web
* String uri = "file:///mnt/sdcard/image.png"; // from SD card
* String uri = "content://media/external/audio/albumart/13"; // from content provider
* String uri = "assets://image.png"; // from assets
* String uri = "drawable://" + R.drawable.image; // from drawables (only images, non-9patch)
*/
public static boolean isImageUriValid(String uri) {
if (TextUtils.isEmpty(uri)) {
return false;
}
if (uriSchemes == null) {
uriSchemes = new ArrayList<>();
for (ImageDownloader.Scheme scheme : ImageDownloader.Scheme.values()) {
uriSchemes.add(scheme.name().toLowerCase());
}
}
for (String scheme : uriSchemes) {
if (uri.toLowerCase().startsWith(scheme)) {
return true;
}
}
return false;
}
/**
* 构建头像缓存
*/
public static void buildAvatarCache(List<String> accounts) {
if (accounts == null || accounts.isEmpty()) {
return;
}
UserInfoProvider.UserInfo userInfo;
for (String account : accounts) {
userInfo = NimUIKit.getUserInfoProvider().getUserInfo(account);
if (userInfo != null) {
asyncLoadAvatarBitmapToCache(userInfo.getAvatar());
}
}
LogUtil.i(TAG, "build avatar cache completed, avatar count =" + accounts.size());
}
/**
* 获取通知栏提醒所需的头像位图,只存内存缓存中取,如果没有则返回空,自动发起异步加载
*/
public static Bitmap getNotificationBitmapFromCache(String url) {
Bitmap cachedBitmap = getMemoryCachedAvatarBitmap(url);
if (cachedBitmap == null) {
asyncLoadAvatarBitmapToCache(url);
} else {
return BitmapUtil.resizeBitmap(cachedBitmap,
HeadImageView.DEFAULT_AVATAR_NOTIFICATION_ICON_SIZE,
HeadImageView.DEFAULT_AVATAR_NOTIFICATION_ICON_SIZE);
}
return null;
}
/**
* 从ImageLoader内存缓存中取出头像位图
*/
private static Bitmap getMemoryCachedAvatarBitmap(String url) {
if (url == null || !isImageUriValid(url)) {
return null;
}
String key = HeadImageView.getAvatarCacheKey(url);
// DiskCacheUtils.findInCache(uri, ImageLoader.getInstance().getDiskCache() 查询磁盘缓存示例
List<Bitmap> bitmaps = MemoryCacheUtils.findCachedBitmapsForImageUri(key, ImageLoader.getInstance().getMemoryCache());
if (bitmaps.size() > 0) {
return bitmaps.get(0);
}
return null;
}
/**
* 异步加载头像位图到ImageLoader内存缓存
*/
private static void asyncLoadAvatarBitmapToCache(String url) {
if (url == null || !isImageUriValid(url)) {
return;
}
String key = HeadImageView.getAvatarCacheKey(url);
ImageLoader.getInstance().loadImage(key,
new ImageSize(HeadImageView.DEFAULT_AVATAR_THUMB_SIZE, HeadImageView.DEFAULT_AVATAR_THUMB_SIZE),
avatarLoadOption, null);
}
/**
* 头像ImageLoader加载配置
*/
private static DisplayImageOptions avatarLoadOption = createImageOptions();
private static final DisplayImageOptions createImageOptions() {
return new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
}
}