栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Glide相关

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Glide相关

二.Glide使用的几个设计模式:
1、 单例模式
a) 饿汉式(静态常量)
优点:这种写法比较简单,就是在类装载的时候就完成实例化。避免了线程同步问题。
缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。

b) 饿汉式(静态代码块)
同上

c) 懒汉式(线程不安全)

d) 懒汉式(线程安全,同步方法)
缺点:效率低。

e) 懒汉式(同步代码块)
缺点:线程不安全

f) 双重检查

g) 静态内部类
静态内部类方式在Singleton类被装载时并不会立即实例化,而是在需要实例化时,调用getInstance方法,才会装载SingletonInstance类,从而完成Singleton的实例化。
类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。
优点:避免了线程不安全,延迟加载,效率高。

h) 枚举
线程安全,防止序列化反射攻击

2、 空对象模式
https://blog.csdn.net/qq_16498553/article/details/106821947?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_title~default-0-106821947-blog-106281772.pc_relevant_multi_platform_whitelistv2&spm=1001.2101.3001.4242.1&utm_relevant_index=3

package com.funshion.player;

public class User {
String id;
String name;
String password;
String phone;

private User(Builder builder) {
    id = builder.id;
    name = builder.name;
    password = builder.password;
    phone = builder.phone;
}

public String getId() {
    return id;
}

public String getName() {
    return name;
}

public String getPassword() {
    return password;
}

public String getPhone() {
    return phone;
}

@Override
public String toString() {
    return "User{" +
            "id='" + id + ''' +
            ", name='" + name + ''' +
            ", password='" + password + ''' +
            ", phone='" + phone + ''' +
            '}';
}

public static final class Builder {
    private String id;
    private String name;
    private String password;
    private String phone;

    public Builder() {
    }

    public Builder id(String val) {
        id = val;
        return this;
    }

    public Builder name(String val) {
        name = val;
        return this;
    }

    public Builder password(String val) {
        password = val;
        return this;
    }

    public Builder phone(String val) {
        phone = val;
        return this;
    }

    public User build() {
        return new User(this);
    }
}

}

package com.funshion.player;

public class Test {
public static void main(String[] args) {
User user=new User.Builder().id(“1”).name(“张三”).password(“123456”)
.phone(“15820638007”).build();
System.out.println(user.toString());
}
}

Glide 加载原理
Glide.with(context)

GeneratedAppGlideModuleImpl
AppGlideModule
LibraryGlideModule

applicationContext.registerComponentCallbacks(glide);
1:Activity在接收到Configuration变化时会销毁重建 调用此方法
2:内存不够了,如果没专门指定触发时机,那它会发生在所有的后台进程都被干掉的时候(在service和前台UI被干掉之前);这个方法结束后系统会触发GC。

sourceExecutor
源线程池
diskCacheExecutor
磁盘缓存线程池
animationExecutor
动画线程池
MemorySizeCalculator
动态计算内存缓存大小

arrayPoolSize =
        isLowMemoryDevice(builder.activityManager)
                ? builder.arrayPoolSizeBytes / LOW_MEMORY_BYTE_ARRAY_POOL_DIVISOR
                : builder.arrayPoolSizeBytes;
//其中会先获取当前进程可使用内存大小,
//然后通过判断是否是否为低内存设备乘以相应的系数,
//普通设备是乘以 0.4,低内存为 0.33,这样得到的是 Glide 可使用的最大内存阈值 maxSize
int maxSize =
        getMaxSize(
                builder.activityManager, builder.maxSizeMultiplier, builder.lowMemoryMaxSizeMultiplier);

int widthPixels = builder.screenDimensions.getWidthPixels();
int heightPixels = builder.screenDimensions.getHeightPixels();
//计算一张格式为 ARGB_8888 ,大小为屏幕大小的图片的占用内存大小
//BYTES_PER_ARGB_8888_PIXEL 值为 4
int screenSize = widthPixels * heightPixels * BYTES_PER_ARGB_8888_PIXEL;

int targetBitmapPoolSize = Math.round(screenSize * builder.bitmapPoolScreens);

int targetMemoryCacheSize = Math.round(screenSize * builder.memoryCacheScreens);
//去掉 ArrayPool 占用的内存后还剩余的内存
int availableSize = maxSize - arrayPoolSize;

if (targetMemoryCacheSize + targetBitmapPoolSize <= availableSize) {
    //未超出内存限制
    memoryCacheSize = targetMemoryCacheSize;
    bitmapPoolSize = targetBitmapPoolSize;
} else {
    //超出内存限制
    float part = availableSize / (builder.bitmapPoolScreens + builder.memoryCacheScreens);
    memoryCacheSize = Math.round(part * builder.memoryCacheScreens);
    bitmapPoolSize = Math.round(part * builder.bitmapPoolScreens);
}

bitmapPool
bitmap池 复用 Bitmap 从而避免重复创建 Bitmap 而带来的内存浪费
arrayPool
把输入流转化为文件时,需要创建一个新的字节数组,如果不用 ArrayPool,而图片是在列表中加载的,那就会创建很多不必要的的字节数组。
memoryCache
内存缓存
diskCacheFactory
磁盘缓存

Registry:
ModelLoaderRegistry
数据加载器登记处 加载数据
EncoderRegistry
编码器登记处 提供将数据持久化存储到磁盘文件中的功能
ResourceDecoderRegistry
资源解码器登记处 能够将各种类型数据,例如文件、byte数组等数据解码成bitmap或者drawable等资源
ResourceEncoderRegistry
资源编码器登记处 提供将bitmap或者drawable等资源文件进行持久化存储的功能
DataRewinderRegistry
数据重定向登记处 重定向ByteBuffer中的position或者stream中的指针位置等
TranscoderRegistry
转码器登记处 提供将不同资源类型进行转换的能力,例如将bitmap转成drawable等

ImageHeaderParserRegistry
图片头部信息解析器登记处

可以在 AppGlideModule 的 registerComponents() 方法中获取到 registry 实例,通过这个实例就可以替换掉对应的实现。

RequestManager
管理生命周期

    // 代码略...
    private final ActivityFragmentLifecycle lifecycle;
    // 代码略...
    @Override
    public void onStart() {
        super.onStart();
        lifecycle.onStart();
    }

    @Override
    public void onStop() {
        super.onStop();
        lifecycle.onStop();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        lifecycle.onDestroy();
    }
    // 代码略...
}

RequestManager implements LifecycleListener

DefaultConnectivityMonitor
网络变化

Glide.with(imageView.getContext()).load(url)

RequestBuilder

Glide.with(imageView.getContext()).load(url).into()

ImageViewTargetFactory
将imageVIew转换为target

buildRequestRecursive()
创建request

buildThumbnailRequestRecursive()
创建缩略图请求,无论如何都会创建这个

Engine 引擎
所有图片加载渠道公用,管理Jobs,load()方法,EngineJob,DecodeJob工厂创建

活动缓存 -》内存缓存-》磁盘缓存/网络加载

EngineJob.start

根据是否从缓存中加载、是否使用无限制大小线程池、是否使用动画线程池等条件得到相应的线程池

    //执行原因,第一次执行,值为INITIALIZE
    switch (runReason) {
        case INITIALIZE:
            stage = getNextStage(Stage.INITIALIZE);
            currentGenerator = getNextGenerator();
            runGenerators();
            break;
        case SWITCH_TO_SOURCE_SERVICE:
            runGenerators();
            break;
        case DECODE_DATA:
            decodeFromRetrievedData();
            break;
        default:
            throw new IllegalStateException("Unrecognized run reason: " + runReason);
    }
}

//首先明确几种装状态有利于阅读
//RESOURCE_CACHE:原始数据经过转换处理过的数据;
//DATA_CACHE:从服务端获取的原始数据;
//SOURCE:发送网络请求获取数据

    switch (current) {
        case INITIALIZE:
            //根据磁盘缓存策略,判断使用原始数据缓存,还是使用转换处理过的缓存数据。
            return diskCacheStrategy.decodeCachedResource()
                    ? Stage.RESOURCE_CACHE
                    : getNextStage(Stage.RESOURCE_CACHE);
        case RESOURCE_CACHE:
            //根据缓存策略,判断是否使用原始文件缓存。
            return diskCacheStrategy.decodeCachedData()
                    ? Stage.DATA_CACHE
                    : getNextStage(Stage.DATA_CACHE);
        case DATA_CACHE:
            // Skip loading from source if the user opted to only retrieve the resource from cache.
            //如果是只是用缓存,那么就返回FINISH,否则返回SOURCE
            return onlyRetrieveFromCache ? Stage.FINISHED : Stage.SOURCE;
        case SOURCE:
        case FINISHED:
            return Stage.FINISHED;
        default:
            throw new IllegalArgumentException("Unrecognized stage: " + current);
    }
}

    switch (stage) {
        case RESOURCE_CACHE:
            //负责从处理过的数据缓存中查找数据
            return new ResourceCacheGenerator(decodeHelper, this);
        case DATA_CACHE:
            //负责从原始文件缓存中查找数据
            return new DataCacheGenerator(decodeHelper, this);
        case SOURCE:
            //从数据源查找,比如服务器
            return new SourceGenerator(decodeHelper, this);
        case FINISHED:
            return null;
        default:
            throw new IllegalStateException("Unrecognized stage: " + stage);
    }
}

/默认的策略是DiskCacheStrategy.AUTOMATIC
DiskCacheStrategy有五个常量:
DiskCacheStrategy.ALL 使用DATA和RESOURCE缓存远程数据,仅使用RESOURCE来缓存本地数据。
DiskCacheStrategy.NONE 不使用磁盘缓存
DiskCacheStrategy.DATA 在资源解码前就将原始数据写入磁盘缓存
DiskCacheStrategy.RESOURCE 在资源解码后将数据写入磁盘缓存,即经过缩放等转换后的图片资源。
DiskCacheStrategy.AUTOMATIC 根据原始图片数据和资源编码策略来自动选择磁盘缓存策略。
/

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1021352.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号