《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)进行学习。

相关文章
|
数据采集 监控 API
告别手动埋点!Android 无侵入式数据采集方案深度解析
传统的Android应用监控方案需要开发者在代码中手动添加埋点,不仅侵入性强、工作量大,还难以维护。本文深入探讨了基于字节码插桩技术的无侵入式数据采集方案,通过Gradle插件 + AGP API + ASM的技术组合,实现对应用性能、用户行为、网络请求等全方位监控,真正做到零侵入、易集成、高稳定。
1218 102
|
设计模式 人工智能 算法
基于多设计模式的状态扭转设计:策略模式与责任链模式的实战应用
接下来,我会结合实战案例,聊聊如何用「策略模式 + 责任链模式」构建灵活可扩展的状态引擎,让抽奖系统的状态管理从「混乱战场」变成「有序流水线」。
设计模式 存储 人工智能
868 0
|
设计模式 C++
【实战指南】设计模式 - 工厂模式
工厂模式是一种面向对象设计模式,通过定义“工厂”来创建具体产品实例。它包含简单工厂、工厂方法和抽象工厂三种形式,分别适用于不同复杂度的场景。简单工厂便于理解但扩展性差;工厂方法符合开闭原则,适合单一类型产品创建;抽象工厂支持多类型产品创建,但不便于新增产品种类。三者各有优缺点,适用于不同设计需求。
587 86
|
设计模式 存储 缓存
Netty源码—9.性能优化和设计模式
本文主要介绍了Netty的两大性能优化工具、FastThreadLocal的源码和总结、Recycler的设计理念/使用/四个核心组件/初始化/对象获取/对象回收/异线程收割对象和总结,以及Netty设计模式的单例模式和策略模式。
415 53
|
安全 Java Android开发
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
629 0
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
|
设计模式 负载均衡 监控
并发设计模式实战系列(2):领导者/追随者模式
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第二章领导者/追随者(Leader/Followers)模式,废话不多说直接开始~
497 0
|
设计模式 监控 Java
并发设计模式实战系列(1):半同步/半异步模式
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第一章半同步/半异步(Half-Sync/Half-Async)模式,废话不多说直接开始~
705 0
|
设计模式 运维 监控
并发设计模式实战系列(4):线程池
需要建立持续的性能剖析(Profiling)和调优机制。通过以上十二个维度的系统化扩展,构建了一个从。设置合理队列容量/拒绝策略。动态扩容/优化任务处理速度。检查线程栈定位热点代码。调整最大用户进程数限制。CPU占用率100%
875 0
|
设计模式 消息中间件 监控
并发设计模式实战系列(3):工作队列
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第三章,废话不多说直接开始~
425 0

热门文章

最新文章

推荐镜像

更多