Universal-ImageLoader源码流程浅析之(一)--参数配置及主要参数说明

前言

Universal-ImageLoader是一个开源的图片加载框架。
希望能通过走读源码流程的方式,了解图片加载的方式方法。

实例创建

ImageLoader的实例创建。

public static ImageLoader getInstance() {
    if (instance == null) {
        synchronized (ImageLoader.class) {
            if (instance == null) {
                instance = new ImageLoader();
            }
        }
    }
    return instance;
}

在实际的应用中,ImageLoader在app中创建,伴随整个app的生命周期,这是一个单例,通过该单例来进行相关的操作。

ImageLoader.getInstance().init(config);
public synchronized void init(ImageLoaderConfiguration configuration) {
    if (configuration == null) {
        throw new IllegalArgumentException(ERROR_INIT_CONFIG_WITH_NULL);
    }
    if (this.configuration == null) {
        L.d(LOG_INIT_CONFIG);
        engine = new ImageLoaderEngine(configuration);
        this.configuration = configuration;
    } else {
        L.w(WARNING_RE_INIT_CONFIG);
    }
}

这次我们先来看一下init的可配参数有哪些,具体又是如何进行配置的。
从上面的代码可以看到配置是一个ImageLoaderConfiguration的类,通常的配置的内容可以有哪些呢?

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getAppContext())
        .denyCacheImageMultipleSizesInMemory()
        .memoryCache(new WeakMemoryCache())
        .diskCache(new UnlimitedDiskCache(cacheDir))
        .memoryCacheSize(20 * 1024 * 1024)
        .diskCacheSize(200 * 1024 * 1024)
        .diskCacheFileCount(1000)
        .writeDebugLogs()
        .build();

ImageLoaderConfiguration是一个典型的以builder模式设计的类,具体参数的创建方法见下面的源码。

private void initEmptyFieldsWithDefaultValues() {
   if (taskExecutor == null) {
      taskExecutor = DefaultConfigurationFactory
            .createExecutor(threadPoolSize, threadPriority, tasksProcessingType);
   } else {
      customExecutor = true;
   }
   if (taskExecutorForCachedImages == null) {
      taskExecutorForCachedImages = DefaultConfigurationFactory
            .createExecutor(threadPoolSize, threadPriority, tasksProcessingType);
   } else {
      customExecutorForCachedImages = true;
   }
   if (diskCache == null) {
      if (diskCacheFileNameGenerator == null) {
         diskCacheFileNameGenerator = DefaultConfigurationFactory.createFileNameGenerator();
      }
      diskCache = DefaultConfigurationFactory
            .createDiskCache(context, diskCacheFileNameGenerator, diskCacheSize, diskCacheFileCount);
   }
   if (memoryCache == null) {
      memoryCache = DefaultConfigurationFactory.createMemoryCache(context, memoryCacheSize);
   }
   if (denyCacheImageMultipleSizesInMemory) {
      memoryCache = new FuzzyKeyMemoryCache(memoryCache, MemoryCacheUtils.createFuzzyKeyComparator());
   }
   if (downloader == null) {
      downloader = DefaultConfigurationFactory.createImageDownloader(context);
   }
   if (decoder == null) {
      decoder = DefaultConfigurationFactory.createImageDecoder(writeLogs);
   }
   if (defaultDisplayImageOptions == null) {
      defaultDisplayImageOptions = DisplayImageOptions.createSimple();
   }
}

下面逐个来逐个简要说明一下:

taskExecutor

tasks of loading and displaying images

taskExecutorForCachedImages

tasks of displaying cached on disk images

DefaultConfigurationFactory
.createExecutor
源码:

public static Executor createExecutor(int threadPoolSize, int threadPriority,
      QueueProcessingType tasksProcessingType) {
   boolean lifo = tasksProcessingType == QueueProcessingType.LIFO;
   BlockingQueue<Runnable> taskQueue =
         lifo ? new LIFOLinkedBlockingDeque<Runnable>() : new LinkedBlockingQueue<Runnable>();
   return new ThreadPoolExecutor(threadPoolSize, threadPoolSize, 0L, TimeUnit.MILLISECONDS, taskQueue,
         createThreadFactory(threadPriority, "uil-pool-"));
}

相关的默认参数:
/* {@value} /
public static final int DEFAULT_THREAD_POOL_SIZE = 3;
/* {@value} /
public static final int DEFAULT_THREAD_PRIORITY = Thread.NORM_PRIORITY - 2;
/* {@value} /
public static final QueueProcessingType DEFAULT_TASK_PROCESSING_TYPE = QueueProcessingType.FIFO;
从这里可以看到ImageLoader本质上就是通过多线程加载图片,然后上述这三个参数都可以配置,一般采用默认值。

diskCache

DefaultConfigurationFactory.createFileNameGenerator();
最后返回的是:String.valueOf(imageUri.hashCode()),ImageLoader在diskcache中存储的文件都是以hashcode编码的。
DefaultConfigurationFactory
.createDiskCache
有兴趣的同学可以自行走读DiskLruCache的实现。

memoryCache

DefaultConfigurationFactory.createMemoryCache(context, memoryCacheSize);
public static MemoryCache createMemoryCache(Context context, int memoryCacheSize) {
        if (memoryCacheSize == 0) {
            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            int memoryClass = am.getMemoryClass();
            if (hasHoneycomb() && isLargeHeap(context)) {
                memoryClass = getLargeMemoryClass(am);
            }
            memoryCacheSize = 1024 * 1024 * memoryClass / 8;
        }
        return new LruMemoryCache(memoryCacheSize);
    }

默认分配可用内存的1/8。实际通过LruMemoryCache来分配。
他和diskCache类似,都是通过LinkedHashMap来实现lrucache.
当开启.denyCacheImageMultipleSizesInMemory()时
设置拒绝缓存在内存中一个图片多个大小 默认为允许,(同一个图片URL)根据不同大小的imageview保存不同大小图片

memoryCache = new FuzzyKeyMemoryCache(memoryCache, MemoryCacheUtils.createFuzzyKeyComparator());

downloader

Provides retrieving of {@link InputStream} of image by URI from network or file system or app resources.
下载器,具体可以看
com.nostra13.universalimageloader.core.download下的两个文件。
imageloader的downloader比较老,这块不如picasso直接使用okhttp的封装。这块后续再专门描述如何定制。

decoder

最终还是调用bitmapfactory的decodeStream方法进行解压
代码参见:
com.nostra13.universalimageloader.core.decode

decodedBitmap = BitmapFactory.decodeStream(imageStream, null, decodingOptions);

具体的解压参数将在后面的内容中进行说明。

以上就是个人的一些浅解,仅供参考。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值