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

    xiaoxiao2021-03-26  22

    前言

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

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

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

    转载请注明原文地址: https://ju.6miu.com/read-658444.html

    最新回复(0)