《Android 源码设计模式解析与实战》——第2章,第2.9节运用单例模式

简介:

本节书摘来自异步社区《Android 源码设计模式解析与实战》一书中的第2章,第2.9节运用单例模式,作者 何红辉 , 关爱民,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.9 运用单例模式
在Android应用开发过程中,ImageLoader是我们最为常用的开发工具库之一。Android中最著名的ImageLoader就是Universal-Image-Loader(https://github.com/nostra13/Android-Universal-Image- Loader),它的使用过程大概是这样的:

public  void initImageLoader(Context context) {
    // 1. 使用Builder构建ImageLoader的配置对象
    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
        //加载图片的线程数
        .threadPriority(Thread.NORM_PRIORITY - 2)
        //解码图像的大尺寸,将在内存中缓存先前解码图像的小尺寸
        .denyCacheImageMultipleSizesInMemory() 
        //设置磁盘缓存文件名称
        .discCacheFileNameGenerator(new Md5FileNameGenerator())
        //设置加载显示图片队列进程
        .tasksProcessingOrder(QueueProcessingType.LIFO)
        .writeDebugLogs() 
        .build();
    // 2. 使用配置对象初始化ImageLoader
    ImageLoader.getInstance().init(config);
    // 3. 加载图片
    ImageLoader.getInstance().displayImage("图片url", myImageView);
}
代码中出现了熟悉的getInstance()方法,因此,我们猜测这个ImageLoader使用的是单例模式。正好,小民的ImageLoader也是类似的实现,通过一个getInstance函数返回单例对象,具体代码如下:

public final class ImageLoader{
// ImageLoader实例
    private static ImageLoadersInstance;
//网络请求队列
    private RequestQueue mImageQueue;
    // 缓存
    private volatile BitmapCache mCache = new MemoryCache();
    // 图片加载配置对象
    private ImageLoaderConfig mConfig;
    // 私有构造函数
    private ImageLoader() {
    }

    /**
     * 获取ImageLoader单例,DCL形式
     * @return单例对象
     */
    public static ImageLoadergetInstance() {
        if (sInstance == null) {
            synchronized (ImageLoader.class) {
                if (sInstance == null) {
                    sInstance = new ImageLoader();
                }
            }
        }
        return sInstance;
    }

    /**通过配置类初始化ImageLoader,设置线程数量、缓存策略、加载策略等
     * @param config配置对象
     */
    public void init(ImageLoaderConfig config) {
        mConfig = config;
        mCache = mConfig.bitmapCache;
        checkConfig();
        mImageQueue = new RequestQueue(mConfig.threadCount);
        mImageQueue.start();
    }
    // 代码省略
    // 加载图片的接口
    public void displayImage(ImageView imageView, String uri) {
        displayImage(imageView, uri, null, null);
    }
    public void displayImage(ImageView imageView, String uri, ImageListener listener) {
        displayImage(imageView, uri, null, listener);
    }

    public void displayImage(final ImageView imageView, final String uri,
    final DisplayConfig config, final ImageListener listener) {
        BitmapRequest request = new BitmapRequest(imageView, uri, config, listener);
        // 加载的配置对象,如果没有设置,则使用ImageLoader的配置
        request.displayConfig = request.displayConfig != null ? request.displayConfig
                : mConfig.displayConfig;
        // 添加到队列中
        mImageQueue.addRequest(request);
    }
    public void stop() {
        mImageQueue.stop();
    }

    // 图片加载Listener,加载完成后回调给客户端代码
    public static interface ImageListener {
        public void onComplete(ImageView imageView, Bitmap bitmap, String uri);
    }
}

我们的ImageLoader类中将构造函数私有化,并且使用Double Check Lock的形式实现单例,用户通过getInstance方法获取ImageLoader单例对象。在用户使用之前需要使用ImageLoaderConfig来配置ImageLoader,配置合理的情况下才会启动用户指定数量的线程来执行图片加载请求。当用户调用displayImage方法时,ImageLoader会将请求构造成一个BitmapRequest,然后将该请求添加到请求队列中,图片加载线程(RequestDispatcher)会从请求队列(RequestQueue)中获取图片加载请求,然后加载该图片,并且将图片显示到对应的ImageView上,最后将图片缓存到缓存系统中。

在后续章节中将会阐述关于该ImageLoader的更多细节,大家可以到github(https://github.com/ bboyfeiyu/simple_imageloader)下载该库的源代码,并且结合《教你写Android ImageLoader框架》系列博文(地址为http://blog.csdn.net/column/details/android-imageloader.html)进行学习。

相关文章
|
7天前
|
数据采集 消息中间件 监控
Flume数据采集系统设计与配置实战:面试经验与必备知识点解析
【4月更文挑战第9天】本文深入探讨Apache Flume的数据采集系统设计,涵盖Flume Agent、Source、Channel、Sink的核心概念及其配置实战。通过实例展示了文件日志收集、网络数据接收、命令行实时数据捕获等场景。此外,还讨论了Flume与同类工具的对比、实际项目挑战及解决方案,以及未来发展趋势。提供配置示例帮助理解Flume在数据集成、日志收集中的应用,为面试准备提供扎实的理论与实践支持。
21 1
|
16天前
|
XML Java Android开发
Android实现自定义进度条(源码+解析)
Android实现自定义进度条(源码+解析)
49 1
|
16天前
|
监控 前端开发 JavaScript
实战篇:商品API接口在跨平台销售中的有效运用与案例解析
随着电子商务的蓬勃发展,企业为了扩大市场覆盖面,经常需要在多个在线平台上展示和销售产品。然而,手工管理多个平台的库存、价格、商品描述等信息既耗时又容易出错。商品API接口在这一背景下显得尤为重要,它能够帮助企业在不同的销售平台之间实现商品信息的高效同步和管理。本文将通过具体的淘宝API接口使用案例,展示如何在跨平台销售中有效利用商品API接口,以及如何通过代码实现数据的统一管理。
|
24天前
|
设计模式 安全 测试技术
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
58 0
|
29天前
|
存储 搜索推荐 人机交互
Qt鼠标事件全面解析:从基础到实战
Qt鼠标事件全面解析:从基础到实战
114 0
|
20天前
|
安全 Java 数据安全/隐私保护
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
【深入浅出Spring原理及实战】「EL表达式开发系列」深入解析SpringEL表达式理论详解与实际应用
43 1
|
4天前
|
设计模式 存储 Java
Java设计模式:解释一下单例模式(Singleton Pattern)。
`Singleton Pattern`是Java中的创建型设计模式,确保类只有一个实例并提供全局访问点。它通过私有化构造函数,用静态方法返回唯一的实例。类内静态变量存储此实例,对外仅通过静态方法访问。
12 1
|
5天前
|
SQL API 数据库
Python中的SQLAlchemy框架:深度解析与实战应用
【4月更文挑战第13天】在Python的众多ORM(对象关系映射)框架中,SQLAlchemy以其功能强大、灵活性和易扩展性脱颖而出,成为许多开发者首选的数据库操作工具。本文将深入探讨SQLAlchemy的核心概念、功能特点以及实战应用,帮助读者更好地理解和使用这一框架。
|
6天前
|
Java 数据库 Spring
切面编程的艺术:Spring动态代理解析与实战
切面编程的艺术:Spring动态代理解析与实战
19 0
切面编程的艺术:Spring动态代理解析与实战
|
24天前
|
机器学习/深度学习 人工智能 自然语言处理
大模型落地实战指南:从选择到训练,深度解析显卡选型、模型训练技、模型选择巧及AI未来展望---打造AI应用新篇章
大模型落地实战指南:从选择到训练,深度解析显卡选型、模型训练技、模型选择巧及AI未来展望---打造AI应用新篇章
大模型落地实战指南:从选择到训练,深度解析显卡选型、模型训练技、模型选择巧及AI未来展望---打造AI应用新篇章

推荐镜像

更多