www.icesr.com
IT运维工程师的摇篮

浅析Android 开源框架ImageLoader的用法

一、前言
在Android开发中,会经常涉及到显示图片的相关操作,在网上查阅资料,ImageLoader得到大家广泛的使用,本篇文章针对初使用者的一个向导,同时也是自己使用该框架的一个总结,主要包含:

<code>   ## 源码浅析 ##
   ## 使用教程 ##
   ## 用法总结及demo下载 ##
</code>

二、源码浅析
从用法来看,我们在使用该框架的时候,会先做一个初始化操作(一般在Application中),

<code>ImageLoader imageLoader = ImageLoader<span class="hljs-preprocessor">.getInstance</span>()<span class="hljs-comment">;</span>
imageLoader<span class="hljs-preprocessor">.init</span>(ImageLoaderConfiguration imageLoaderConfiguration )<span class="hljs-comment">;</span></code>

我们在源码进入该方法查看:

<code><span class="hljs-keyword">private</span> <span class="hljs-keyword">volatile</span> <span class="hljs-keyword">static</span> ImageLoader instance;

    <span class="hljs-javadoc">/** Returns singleton class instance */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> ImageLoader <span class="hljs-title">getInstance</span>() {
        <span class="hljs-keyword">if</span> (instance == <span class="hljs-keyword">null</span>) {
            <span class="hljs-keyword">synchronized</span> (ImageLoader.class) {
                <span class="hljs-keyword">if</span> (instance == <span class="hljs-keyword">null</span>) {
                    instance = <span class="hljs-keyword">new</span> ImageLoader();
                }
            }
        }
        <span class="hljs-keyword">return</span> instance;
    }

    <span class="hljs-keyword">protected</span> <span class="hljs-title">ImageLoader</span>() {
    }

    <span class="hljs-javadoc">/**
     * Initializes ImageLoader instance with configuration.&lt;br /&gt;
     * If configurations was set before ( {@link #isInited()} == true) then this method does nothing.&lt;br /&gt;
     * To force initialization with new configuration you should {@linkplain #destroy() destroy ImageLoader} at first.
     *
     *<span class="hljs-javadoctag"> @param</span> configuration {@linkplain ImageLoaderConfiguration ImageLoader configuration}
     *<span class="hljs-javadoctag"> @throws</span> IllegalArgumentException if &lt;b&gt;configuration&lt;/b&gt; parameter is null
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">synchronized</span> <span class="hljs-keyword">void</span> <span class="hljs-title">init</span>(ImageLoaderConfiguration configuration) {
        <span class="hljs-keyword">if</span> (configuration == <span class="hljs-keyword">null</span>) {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(ERROR_INIT_CONFIG_WITH_NULL);
        }
        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.configuration == <span class="hljs-keyword">null</span>) {
            L.d(LOG_INIT_CONFIG);
            engine = <span class="hljs-keyword">new</span> ImageLoaderEngine(configuration);
            <span class="hljs-keyword">this</span>.configuration = configuration;
        } <span class="hljs-keyword">else</span> {
            L.w(WARNING_RE_INIT_CONFIG);
        }
    }</code>

获取实例对象的方式用了单例模式,这里我们主要看一下init()这个方法:
根据注释的文档可知初始化时的一些注意事项,该方法主要对engine做初始化:

<code>engine = <span class="hljs-keyword">new</span> ImageLoaderEngine(<span class="hljs-keyword">configuration</span>);</code>

我们继续进入ImageLoaderEngine中看下这个类的构造方法:

<code>ImageLoaderEngine(ImageLoaderConfiguration configuration) {
        this<span class="hljs-preprocessor">.configuration</span> = configuration<span class="hljs-comment">;</span>

        taskExecutor = configuration<span class="hljs-preprocessor">.taskExecutor</span><span class="hljs-comment">;</span>
        taskExecutorForCachedImages = configuration<span class="hljs-preprocessor">.taskExecutorForCachedImages</span><span class="hljs-comment">;</span>

        taskDistributor = DefaultConfigurationFactory<span class="hljs-preprocessor">.createTaskDistributor</span>()<span class="hljs-comment">;</span>
    }</code>

可知,该库是通过Executor对象将线程放入线程池中运行的,此构造方法里面初始化了taskExecutorForCachedImages、taskExecutor、taskDistributor这三个对象,它们都是Executor接口的实例。关于Executor接口,大家可以上网搜一下相关的知识,这里给个参考链接:

http://blog.csdn.net/minword/article/details/20565867

关于初始化的操作我们先看到这里,主要是明白了它是通过Executor来处理任务的。

接下来看下显示图片的操作,同样,我们看下源码:

<code>/**
     * Adds display image task <span class="hljs-keyword">to</span> execution pool. Image will be <span class="hljs-keyword">set</span> <span class="hljs-keyword">to</span> ImageAware when it<span class="hljs-comment">'s turn.&lt;br /&gt;</span>
     * &lt;b&gt;NOTE:&lt;/b&gt; {@link #init(ImageLoaderConfiguration)} method must be called before this method <span class="hljs-keyword">call</span>
     *
     * @param uri              Image URI (i.e. <span class="hljs-string">"http://site.com/image.png"</span>, <span class="hljs-string">"file:///mnt/sdcard/image.png"</span>)
     * @param imageAware       {@linkplain com.nostra13.universalimageloader.core.imageaware.ImageAware Image aware view}
     *                         which should display image
     * @param options          {@linkplain com.nostra13.universalimageloader.core.DisplayImageOptions Options} <span class="hljs-keyword">for</span> image
     *                         decoding <span class="hljs-keyword">and</span> displaying. <span class="hljs-keyword">If</span> &lt;b&gt;<span class="hljs-literal">null</span>&lt;/b&gt; - <span class="hljs-keyword">default</span> display image options
     *                         {@linkplain ImageLoaderConfiguration.Builder#defaultDisplayImageOptions(DisplayImageOptions)
     *                         from configuration} will be used.
     * @param listener         {@linkplain ImageLoadingListener Listener} <span class="hljs-keyword">for</span> image loading process. Listener fires
     *                         events <span class="hljs-keyword">on</span> UI thread <span class="hljs-keyword">if</span> this method <span class="hljs-keyword">is</span> called <span class="hljs-keyword">on</span> UI thread.
     * @param progressListener {@linkplain com.nostra13.universalimageloader.core.listener.ImageLoadingProgressListener
     *                         Listener} <span class="hljs-keyword">for</span> image loading progress. Listener fires events <span class="hljs-keyword">on</span> UI thread <span class="hljs-keyword">if</span> this method
     *                         <span class="hljs-keyword">is</span> called <span class="hljs-keyword">on</span> UI thread. Caching <span class="hljs-keyword">on</span> disk should be enabled <span class="hljs-keyword">in</span>
     *                         {@linkplain com.nostra13.universalimageloader.core.DisplayImageOptions options} <span class="hljs-keyword">to</span> make
     *                         this listener work.
     * @throws IllegalStateException    <span class="hljs-keyword">if</span> {@link #init(ImageLoaderConfiguration)} method wasn<span class="hljs-comment">'t called before</span>
     * @throws IllegalArgumentException <span class="hljs-keyword">if</span> passed &lt;b&gt;imageAware&lt;/b&gt; <span class="hljs-keyword">is</span> <span class="hljs-literal">null</span>
     */
    <span class="hljs-keyword">public</span> void displayImage(<span class="hljs-built_in">String</span> uri, ImageAware imageAware, DisplayImageOptions options,
            ImageLoadingListener listener, ImageLoadingProgressListener progressListener) {
        checkConfiguration();
        <span class="hljs-keyword">if</span> (imageAware == <span class="hljs-literal">null</span>) {
            throw <span class="hljs-keyword">new</span> IllegalArgumentException(ERROR_WRONG_ARGUMENTS);
        }
        <span class="hljs-keyword">if</span> (listener == <span class="hljs-literal">null</span>) {
            listener = emptyListener;
        }
        <span class="hljs-keyword">if</span> (options == <span class="hljs-literal">null</span>) {
            options = configuration.defaultDisplayImageOptions;
        }

        <span class="hljs-keyword">if</span> (TextUtils.<span class="hljs-built_in">isEmpty</span>(uri)) {
            engine.cancelDisplayTaskFor(imageAware);
            listener.onLoadingStarted(uri, imageAware.getWrappedView());
            <span class="hljs-keyword">if</span> (options.shouldShowImageForEmptyUri()) {
                imageAware.setImageDrawable(options.getImageForEmptyUri(configuration.resources));
            } <span class="hljs-keyword">else</span> {
                imageAware.setImageDrawable(<span class="hljs-literal">null</span>);
            }
            listener.onLoadingComplete(uri, imageAware.getWrappedView(), <span class="hljs-literal">null</span>);
            return;
        }

        ImageSize targetSize = ImageSizeUtils.defineTargetSizeForView(imageAware, configuration.getMaxImageSize());
        <span class="hljs-built_in">String</span> memoryCacheKey = MemoryCacheUtils.generateKey(uri, targetSize);
        engine.prepareDisplayTaskFor(imageAware, memoryCacheKey);

        listener.onLoadingStarted(uri, imageAware.getWrappedView());

        Bitmap bmp = configuration.memoryCache.<span class="hljs-keyword">get</span>(memoryCacheKey);
        <span class="hljs-keyword">if</span> (bmp != <span class="hljs-literal">null</span> &amp;&amp; !bmp.isRecycled()) {
            L.d(LOG_LOAD_IMAGE_FROM_MEMORY_CACHE, memoryCacheKey);

            <span class="hljs-keyword">if</span> (options.shouldPostProcess()) {
                ImageLoadingInfo imageLoadingInfo = <span class="hljs-keyword">new</span> ImageLoadingInfo(uri, imageAware, targetSize, memoryCacheKey,
                        options, listener, progressListener, engine.getLockForUri(uri));
                ProcessAndDisplayImageTask displayTask = <span class="hljs-keyword">new</span> ProcessAndDisplayImageTask(engine, bmp, imageLoadingInfo,
                        defineHandler(options));
                <span class="hljs-keyword">if</span> (options.isSyncLoading()) {
                    displayTask.run();
                } <span class="hljs-keyword">else</span> {
                    engine.submit(displayTask);
                }
            } <span class="hljs-keyword">else</span> {
                options.getDisplayer().display(bmp, imageAware, LoadedFrom.MEMORY_CACHE);
                listener.onLoadingComplete(uri, imageAware.getWrappedView(), bmp);
            }
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">if</span> (options.shouldShowImageOnLoading()) {
                imageAware.setImageDrawable(options.getImageOnLoading(configuration.resources));
            } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (options.isResetViewBeforeLoading()) {
                imageAware.setImageDrawable(<span class="hljs-literal">null</span>);
            }

            ImageLoadingInfo imageLoadingInfo = <span class="hljs-keyword">new</span> ImageLoadingInfo(uri, imageAware, targetSize, memoryCacheKey,
                    options, listener, progressListener, engine.getLockForUri(uri));
            LoadAndDisplayImageTask displayTask = <span class="hljs-keyword">new</span> LoadAndDisplayImageTask(engine, imageLoadingInfo,
                    defineHandler(options));
            <span class="hljs-keyword">if</span> (options.isSyncLoading()) {
                displayTask.run();
            } <span class="hljs-keyword">else</span> {
                engine.submit(displayTask);
            }
        }
    }</code>

可知,我们将显示图片的任务加入到线程池中,之后ImageAware进行工作,
这里看下这段代码:

<code><span class="hljs-keyword">if</span> (options == <span class="hljs-keyword">null</span>) {
            options = configuration.defaultDisplayImageOptions;
}</code>

其实就是我们设置的图片显示失败时显示的图片,这边是我们设置null时,使用了默认的图片。
回到刚才,我们发现该类读取了很多的配置参数信息,其实是我们初始化时,配置的参数,主要是配置缓存相关信息,见第二部分,使用教程。最后我们通过ImageLoaderEngine来执行显示图片的任务。

<code>engine<span class="hljs-preprocessor">.submit</span>(displayTask)<span class="hljs-comment">;</span></code>

submit内部方法(ImageLoaderEngine类中):

<code><span class="hljs-javadoc">/** Submits task to execution pool */</span>
    <span class="hljs-keyword">void</span> submit(ProcessAndDisplayImageTask task) {
        initExecutorsIfNeed();
        taskExecutorForCachedImages.execute(task);
    }

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title">initExecutorsIfNeed</span>() {
        <span class="hljs-keyword">if</span> (!configuration.customExecutor &amp;&amp; ((ExecutorService) taskExecutor).isShutdown()) {
            taskExecutor = createTaskExecutor();
        }
        <span class="hljs-keyword">if</span> (!configuration.customExecutorForCachedImages &amp;&amp; ((ExecutorService) taskExecutorForCachedImages)
                .isShutdown()) {
            taskExecutorForCachedImages = createTaskExecutor();
        }
    }</code>

以上是主要的一些源码浅析,想了解更多的可以自行翻阅源码查看。接下来我们介绍一下简单的使用教程。

三、使用教程

首先获取该库:我用的是gradle配置:

在gradle中加入:

<code>compile <span class="hljs-string">'com.nostra13.universalimageloader:universal-image-loader:1.9.3'</span></code>

Maven 配置:

<code><span class="hljs-tag">&lt;<span class="hljs-title">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">groupid</span>&gt;</span>com.nostra13.universalimageloader<span class="hljs-tag">&lt;/<span class="hljs-title">groupid</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">artifactId</span>&gt;</span>universal-image-loader<span class="hljs-tag">&lt;/<span class="hljs-title">artifactid</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-title">version</span>&gt;</span>1.9.3<span class="hljs-tag">&lt;/<span class="hljs-title">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-title">dependency</span>&gt;</span></code>

在AndroidManifest.xml中加入(涉及到图片缓存读写路径,访问网络操作):

<code><span class="hljs-tag">&lt;<span class="hljs-title">uses-permission</span> <span class="hljs-attribute">android:name</span>=<span class="hljs-value">"android.permission.WRITE_EXTERNAL_STORAGE"</span> /&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-title">uses-permission</span> <span class="hljs-attribute">android:name</span>=<span class="hljs-value">"android.permission.INTERNET"</span> /&gt;</span></code>

之后我们就可以代码编写。
首先在activity_main中设置一个显示图片的控件:

<code>  <span class="hljs-tag">&lt;<span class="hljs-title">ImageView
</span>        <span class="hljs-attribute">android:id</span>=<span class="hljs-value">"@+id/user_image"</span>
        <span class="hljs-attribute">android:layout_width</span>=<span class="hljs-value">"64dp"</span>
        <span class="hljs-attribute">android:layout_height</span>=<span class="hljs-value">"64dp"</span>/&gt;</span></code>

在MainActivity中使用ImageLoader加载一张网络图片:

<code>imageView = (ImageView) findViewById(R<span class="hljs-preprocessor">.id</span><span class="hljs-preprocessor">.user</span>_image)<span class="hljs-comment">;</span>
ImageLoaderUtil<span class="hljs-preprocessor">.init</span>(this)<span class="hljs-comment">;</span>
String url_image = <span class="hljs-string">"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWsK1HF6hhy/it/u=3266622398,4228444443&amp;fm=116&amp;gp=0.jpg"</span><span class="hljs-comment">;</span>
ImageLoaderUtil<span class="hljs-preprocessor">.displayImage</span>(url_image,imageView,ImageLoaderUtil<span class="hljs-preprocessor">.getAvatarDisplayOptions</span>())<span class="hljs-comment">;</span></code>

显示的效果图:
正常状态下显示的图片

当网络路径不存在图片时(显示预设的图片):
路径出错时显示的预设图片

ImageLoaderUtil是我自己封装的一个类:

主要我们得编写init()方法:

<code><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">init</span>(Context context) {
        File cacheDir = getCacheDirectory(context);  <span class="hljs-comment">//缓存文件夹路径</span>

        ImageLoaderConfiguration config = <span class="hljs-keyword">new</span> ImageLoaderConfiguration.Builder(context)
                .memoryCacheExtraOptions(<span class="hljs-number">480</span>, <span class="hljs-number">800</span>) <span class="hljs-comment">// default = device screen dimensions 内存缓存文件的最大长宽</span>
                .diskCacheExtraOptions(<span class="hljs-number">480</span>, <span class="hljs-number">800</span>, <span class="hljs-keyword">null</span>)  <span class="hljs-comment">// 本地缓存的详细信息(缓存的最大长宽),最好不要设置这个</span>
<span class="hljs-comment">//                .taskExecutor("")</span>
<span class="hljs-comment">//        .taskExecutorForCachedImages("")</span>
        .threadPoolSize(<span class="hljs-number">3</span>) <span class="hljs-comment">// default  线程池内加载的数量</span>
                .threadPriority(Thread.NORM_PRIORITY - <span class="hljs-number">2</span>) <span class="hljs-comment">// default 设置当前线程的优先级</span>
                .tasksProcessingOrder(QueueProcessingType.FIFO) <span class="hljs-comment">// default</span>
                .denyCacheImageMultipleSizesInMemory()
                .memoryCache(<span class="hljs-keyword">new</span> LruMemoryCache(<span class="hljs-number">2</span> * <span class="hljs-number">1024</span> * <span class="hljs-number">1024</span>)) <span class="hljs-comment">//可以通过自己的内存缓存实现</span>
                .memoryCacheSize(<span class="hljs-number">2</span> * <span class="hljs-number">1024</span> * <span class="hljs-number">1024</span>)  <span class="hljs-comment">// 内存缓存的最大值</span>
                .memoryCacheSizePercentage(<span class="hljs-number">13</span>) <span class="hljs-comment">// default</span>
                .diskCache(<span class="hljs-keyword">new</span> UnlimitedDiscCache(cacheDir)) <span class="hljs-comment">// default 可以自定义缓存路径</span>
                .diskCacheSize(<span class="hljs-number">50</span> * <span class="hljs-number">1024</span> * <span class="hljs-number">1024</span>) <span class="hljs-comment">// 50 Mb sd卡(本地)缓存的最大值</span>
                .diskCacheFileCount(<span class="hljs-number">100</span>)  <span class="hljs-comment">// 可以缓存的文件数量</span>
                <span class="hljs-comment">// default为使用HASHCODE对UIL进行加密命名, 还可以用MD5(new Md5FileNameGenerator())加密</span>
                .diskCacheFileNameGenerator(<span class="hljs-keyword">new</span> HashCodeFileNameGenerator())
                .imageDownloader(<span class="hljs-keyword">new</span> BaseImageDownloader(context)) <span class="hljs-comment">// default</span>
                .imageDecoder(<span class="hljs-keyword">new</span> BaseImageDecoder(<span class="hljs-keyword">true</span>)) <span class="hljs-comment">// l</span>
                .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) <span class="hljs-comment">// default</span>
                .writeDebugLogs() <span class="hljs-comment">// 打印debug log</span>
                .build(); <span class="hljs-comment">//开始构建</span>
        ImageLoader.getInstance().init(config);
    }</code>

可参照注释对应了解参数信息。

完整的ImageLoaderUtil类:

<code><span class="hljs-keyword">package</span> constraintlayout.test.test.viviant.imageloadertest.util;

<span class="hljs-keyword">import</span> android.content.Context;
<span class="hljs-keyword">import</span> android.util.Log;
<span class="hljs-keyword">import</span> android.widget.ImageView;

<span class="hljs-keyword">import</span> com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache;
<span class="hljs-keyword">import</span> com.nostra13.universalimageloader.cache.disc.naming.HashCodeFileNameGenerator;
<span class="hljs-keyword">import</span> com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache;
<span class="hljs-keyword">import</span> com.nostra13.universalimageloader.core.DisplayImageOptions;
<span class="hljs-keyword">import</span> com.nostra13.universalimageloader.core.ImageLoader;
<span class="hljs-keyword">import</span> com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
<span class="hljs-keyword">import</span> com.nostra13.universalimageloader.core.assist.QueueProcessingType;
<span class="hljs-keyword">import</span> com.nostra13.universalimageloader.core.decode.BaseImageDecoder;
<span class="hljs-keyword">import</span> com.nostra13.universalimageloader.core.download.BaseImageDownloader;

<span class="hljs-keyword">import</span> java.io.File;

<span class="hljs-keyword">import</span> constraintlayout.test.test.viviant.imageloadertest.R;

<span class="hljs-javadoc">/**
 * 作者:viviant on 2016/6/30 09:22
 * 描述:
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ImageLoaderUtil</span> {</span>

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> String PICTURE_CACHE_DIR = <span class="hljs-string">"picture"</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> String TAG = <span class="hljs-string">"ImageLoaderUtil"</span>;

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">init</span>(Context context) {
        File cacheDir = getCacheDirectory(context);  <span class="hljs-comment">//缓存文件夹路径</span>

        ImageLoaderConfiguration config = <span class="hljs-keyword">new</span> ImageLoaderConfiguration.Builder(context)
                .memoryCacheExtraOptions(<span class="hljs-number">480</span>, <span class="hljs-number">800</span>) <span class="hljs-comment">// default = device screen dimensions 内存缓存文件的最大长宽</span>
                .diskCacheExtraOptions(<span class="hljs-number">480</span>, <span class="hljs-number">800</span>, <span class="hljs-keyword">null</span>)  <span class="hljs-comment">// 本地缓存的详细信息(缓存的最大长宽),最好不要设置这个</span>
<span class="hljs-comment">//                .taskExecutor("")</span>
<span class="hljs-comment">//        .taskExecutorForCachedImages("")</span>
        .threadPoolSize(<span class="hljs-number">3</span>) <span class="hljs-comment">// default  线程池内加载的数量</span>
                .threadPriority(Thread.NORM_PRIORITY - <span class="hljs-number">2</span>) <span class="hljs-comment">// default 设置当前线程的优先级</span>
                .tasksProcessingOrder(QueueProcessingType.FIFO) <span class="hljs-comment">// default</span>
                .denyCacheImageMultipleSizesInMemory()
                .memoryCache(<span class="hljs-keyword">new</span> LruMemoryCache(<span class="hljs-number">2</span> * <span class="hljs-number">1024</span> * <span class="hljs-number">1024</span>)) <span class="hljs-comment">//可以通过自己的内存缓存实现</span>
                .memoryCacheSize(<span class="hljs-number">2</span> * <span class="hljs-number">1024</span> * <span class="hljs-number">1024</span>)  <span class="hljs-comment">// 内存缓存的最大值</span>
                .memoryCacheSizePercentage(<span class="hljs-number">13</span>) <span class="hljs-comment">// default</span>
                .diskCache(<span class="hljs-keyword">new</span> UnlimitedDiscCache(cacheDir)) <span class="hljs-comment">// default 可以自定义缓存路径</span>
                .diskCacheSize(<span class="hljs-number">50</span> * <span class="hljs-number">1024</span> * <span class="hljs-number">1024</span>) <span class="hljs-comment">// 50 Mb sd卡(本地)缓存的最大值</span>
                .diskCacheFileCount(<span class="hljs-number">100</span>)  <span class="hljs-comment">// 可以缓存的文件数量</span>
                <span class="hljs-comment">// default为使用HASHCODE对UIL进行加密命名, 还可以用MD5(new Md5FileNameGenerator())加密</span>
                .diskCacheFileNameGenerator(<span class="hljs-keyword">new</span> HashCodeFileNameGenerator())
                .imageDownloader(<span class="hljs-keyword">new</span> BaseImageDownloader(context)) <span class="hljs-comment">// default</span>
                .imageDecoder(<span class="hljs-keyword">new</span> BaseImageDecoder(<span class="hljs-keyword">true</span>)) <span class="hljs-comment">// l</span>
                .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) <span class="hljs-comment">// default</span>
                .writeDebugLogs() <span class="hljs-comment">// 打印debug log</span>
                .build(); <span class="hljs-comment">//开始构建</span>
        ImageLoader.getInstance().init(config);
    }

    <span class="hljs-javadoc">/**
     * 获取缓存文件
     *
     *<span class="hljs-javadoctag"> @param</span> context
     *<span class="hljs-javadoctag"> @return</span>
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">static</span> File <span class="hljs-title">getCacheDirectory</span>(Context context) {
        String cacheDir = SystemUtility.getAppCachePath();
        <span class="hljs-keyword">return</span> createDir(cacheDir + PICTURE_CACHE_DIR);
    }

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">static</span> File <span class="hljs-title">createDir</span>(String dir) {
        File appCacheDir = <span class="hljs-keyword">new</span> File(dir);
        <span class="hljs-keyword">if</span> (!appCacheDir.exists()) {
            <span class="hljs-keyword">if</span> (!appCacheDir.mkdirs()) {
                Log.i(TAG, <span class="hljs-string">"createDir# Unable to create external cache directory"</span>);
                <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
            }
        }
        <span class="hljs-keyword">return</span> appCacheDir;
    }

    <span class="hljs-javadoc">/**
     *显示出错,替换的图片
     *<span class="hljs-javadoctag"> @return</span>
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> DisplayImageOptions <span class="hljs-title">getAvatarDisplayOptions</span>() {
        DisplayImageOptions avatarOptions = <span class="hljs-keyword">new</span> DisplayImageOptions.Builder()
                .showImageOnLoading(R.drawable.error)
                .showImageForEmptyUri(R.drawable.error)
                .showImageOnFail(R.drawable.error)
                .cacheInMemory(<span class="hljs-keyword">true</span>).cacheOnDisk(<span class="hljs-keyword">true</span>).build();
        <span class="hljs-keyword">return</span> avatarOptions;
    }

    <span class="hljs-javadoc">/**
     * 显示图片
     *
     *<span class="hljs-javadoctag"> @param</span> url
     *<span class="hljs-javadoctag"> @param</span> imageView
     *<span class="hljs-javadoctag"> @param</span> options
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">displayImage</span>(String url, ImageView imageView,
                                    DisplayImageOptions options) {
        ImageLoader.getInstance().displayImage(url, imageView, options);
    }

}</code>

四、用法总结及源码下载:

ImageLoader的用法总的来说还是很便捷的,我们可以设置相应的参数来初始化配置,并且它的优点是应用进行大量的访问网络图片。以上是我对该框架的一些使用方法进行总结,不足之处,欢迎批评。

源码下载(AndroidStudio直接导入):
https://github.com/viviant1224/ImageLoaderTest

未经允许不得转载:冰点网络 » 浅析Android 开源框架ImageLoader的用法

分享到:更多 ()

评论 抢沙发

评论前必须登录!