当前位置: 首页 > news >正文

为什么实验楼网站上做实验这么卡批量外链工具

为什么实验楼网站上做实验这么卡,批量外链工具,做网站怎么复制视频链接,网站制作要学哪些背景: 相册-图片后处理场景,需要先展示一张原图,同时后台对图片进行算法优化,完成优化之后无缝替换原图展示,同时保证后续都展示算法优化后的图片 图片加载采用 Glide 库实现 画重点: 相册场景&#xff…

背景:

相册-图片后处理场景,需要先展示一张原图,同时后台对图片进行算法优化,完成优化之后无缝替换原图展示,同时保证后续都展示算法优化后的图片

图片加载采用 Glide 库实现

画重点:

  1. 相册场景:意味着存在图片缓存的复用

  2. 无缝替换:切换过程要很丝滑,不能有闪烁等现象

  3. 后续展示优化后的图片:说明后续缓存要复用算法优化后的,不能用原图

  4. 因为是对图片进行优化,所以原图和算法优化后的图片文件名一样

最开始的想法:

步骤:

  1. 先加载原图展示

  2. 等图片算法优化,重新调用 glide 加载一遍

结果:

  1. 重新加载之后,还是原图效果

Glide 缓存机制

基于上述原因,专门研究了下 Glide 的缓存机制,重点是缓存的读取这一块

四级缓存机制

Glide 采用四级缓存机制,主要分成两个模块,内存缓存,硬盘缓存

  • 内存缓存:防止应用重复将图片数据读到内存中
  • 硬盘缓存:防止应用重复从网络或者其他地方重复下载和读取数据
  • 缓存Key:既然有缓存,那肯定需要对应的缓存Key,通过按照一定规则生成缓存key之后,根据key从缓存集中取出对应缓存复用

这里先简单讲下四级缓存机制,然后再跟着源码过一遍

内存缓存-lru缓存:

Glide 在内存中维持的一个缓存 map,通过 lru 算法实现内存管理

private final LinkedHashMap<T, Y> cache = new LinkedHashMap<T, Y>(100, 0.75f, true);
​
T:缓存Key
Y:缓存资源

内存缓存-弱引用缓存:

Glide 在内存中维持的一个弱引用缓存 map,由于是弱引用,这就意味着内存不足的时候先销毁这个

private final Map<Key, WeakReference<EngineResource<?>>> activeResources;

硬盘缓存-转换过缓存:

Glide 在硬盘上的缓存,该缓存是经过各种变换后的缓存,不是原始图片

硬盘缓存-原始图片缓存:

Glide 在硬盘上的缓存,该缓存是原始图片缓存

Glide 缓存加载流程:

public <T, Z, R> LoadStatus load(Key signature, int width, int height, DataFetcher<T> fetcher,DataLoadProvider<T, Z> loadProvider, Transformation<Z> transformation, ResourceTranscoder<Z, R> transcoder,Priority priority, boolean isMemoryCacheable, DiskCacheStrategy diskCacheStrategy, ResourceCallback cb) {Util.assertMainThread();long startTime = LogTime.getLogTime();
​final String id = fetcher.getId();// 1. 生成 缓存key,可以看出 key 的生成用到很多参数,比如 id(图片路径)、signature、width、height,还有 transformationEngineKey key = keyFactory.buildKey(id, signature, width, height, loadProvider.getCacheDecoder(),loadProvider.getSourceDecoder(), transformation, loadProvider.getEncoder(),transcoder, loadProvider.getSourceEncoder());
​// 2. 先从内存缓存-lru缓存中拿缓存,如果拿到缓存调用 onResourceReadyEngineResource<?> cached = loadFromCache(key, isMemoryCacheable);if (cached != null) {cb.onResourceReady(cached);if (Log.isLoggable(TAG, Log.VERBOSE)) {logWithTimeAndKey("Loaded resource from cache", startTime, key);}return null;}// 3. 内存缓存-lru中没有缓存,则从弱引用缓存中拿,如果拿到调用 onResourceReadyEngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);if (active != null) {cb.onResourceReady(active);if (Log.isLoggable(TAG, Log.VERBOSE)) {logWithTimeAndKey("Loaded resource from active resources", startTime, key);}return null;}// 4. 内存缓存-弱引用中也没有缓存,从硬盘缓存中拿或加载文件地址,不管是拿硬盘缓存还是加载文件,涉及到IO操作,需要子线程处理EngineJob current = jobs.get(key);if (current != null) {current.addCallback(cb);if (Log.isLoggable(TAG, Log.VERBOSE)) {logWithTimeAndKey("Added to existing load", startTime, key);}return new LoadStatus(cb, current);}
​EngineJob engineJob = engineJobFactory.build(key, isMemoryCacheable);DecodeJob<T, Z, R> decodeJob = new DecodeJob<T, Z, R>(key, width, height, fetcher, loadProvider, transformation,transcoder, diskCacheProvider, diskCacheStrategy, priority);EngineRunnable runnable = new EngineRunnable(engineJob, decodeJob, priority);jobs.put(key, engineJob);engineJob.addCallback(cb);engineJob.start(runnable);
​if (Log.isLoggable(TAG, Log.VERBOSE)) {logWithTimeAndKey("Started new load", startTime, key);}return new LoadStatus(cb, engineJob);
}

内存缓存-lru缓存中拿缓存:

private EngineResource<?> loadFromCache(Key key, boolean isMemoryCacheable) {if (!isMemoryCacheable) {return null;}// 如果从 lru 中能拿到缓存,将该缓存从 lru 缓存中移除,并存入 弱引用缓存EngineResource<?> cached = getEngineResourceFromCache(key);if (cached != null) {cached.acquire();activeResources.put(key, new ResourceWeakReference(key, cached, getReferenceQueue()));}return cached;
}

从硬盘缓存中拿或加载文件地址:

private Resource<?> decode() throws Exception {// 这里有个策略判断,只有支持硬盘缓存策略,才能从硬盘中拿缓存if (isDecodingFromCache()) {// 从硬盘缓存中拿return decodeFromCache();} else {// 加载文件return decodeFromSource();}
}​
// 从硬盘缓存中拿
private Resource<?> decodeFromCache() throws Exception {Resource<?> result = null;try {// 5. 从硬盘缓存-转换过缓存中拿result = decodeJob.decodeResultFromCache();} catch (Exception e) {if (Log.isLoggable(TAG, Log.DEBUG)) {Log.d(TAG, "Exception decoding result from cache: " + e);}}
​if (result == null) {// 6. 硬盘缓存-转换过缓存中拿不到,从原始图片缓存中拿result = decodeJob.decodeSourceFromCache();}return result;
}
​
// 从硬盘缓存-转换过缓存中拿
public Resource<Z> decodeResultFromCache() throws Exception {if (!diskCacheStrategy.cacheResult()) {return null;}
​long startTime = LogTime.getLogTime();Resource<T> transformed = loadFromCache(resultKey);if (Log.isLoggable(TAG, Log.VERBOSE)) {logWithTimeAndKey("Decoded transformed from cache", startTime);}startTime = LogTime.getLogTime();Resource<Z> result = transcode(transformed);if (Log.isLoggable(TAG, Log.VERBOSE)) {logWithTimeAndKey("Transcoded transformed from cache", startTime);}return result;
}
​
// 从硬盘缓存-原始图片缓存中拿
public Resource<Z> decodeSourceFromCache() throws Exception {if (!diskCacheStrategy.cacheSource()) {return null;}
​long startTime = LogTime.getLogTime();// 这里值得注意的是,这里用的key和其他三个缓存中用到的不一样,这里用的是 resultKey.getOriginalKey() 就是原始图片地址,不过也能理解,加载原始图片缓存,也不需要额外的key信息,只需要文件地址就行了Resource<T> decoded = loadFromCache(resultKey.getOriginalKey());if (Log.isLoggable(TAG, Log.VERBOSE)) {logWithTimeAndKey("Decoded source from cache", startTime);}return transformEncodeAndTranscode(decoded);
}

理完Glide的加载机制之后,就很好理解为什么重新加载之后还是原图,所以进行了优化

优化方案二

加载原图时:

glideOptions = new RequestOptions().signature(new ObjectKey(signatureKey));

加载优化后图片时:

glideOptions = new RequestOptions();

加载原图时多调用了 signature 方法,这样加载优化后图片时,由于和加载原图时的缓存key不一样,会重新进行加载

优化方案二解决了优化图片不加载问题,但是由于重新加载图片,会导致切换过程出现很明显的闪烁,这里可以通过 placeholder 方法优化

优化方案三

// 1. 获取当前 imageView 的 drawable
Drawable drawable = imageView.getDrawable();
Bitmap placeholderBitmap = null;
// 2. drawable 转成 bitmap
if(drawable instanceof BitmapDrawable){placeholderBitmap = ((BitmapDrawable) drawable).getBitmap();
}
// 3. 由于 imageView 的 drawable 可能会被回收,所以需要将 bitmap 重新 clone 一份
Bitmap copiedBitmap = null;
if(placeholderBitmap != null){copiedBitmap = placeholderBitmap.copy(placeholderBitmap.getConfig(), true);
}
// 4. 将 bitmap 作为 占位符传入
if(copiedBitmap != null && !copiedBitmap.isRecycled()){glideOptions = new RequestOptions().frame(0).placeholder(new BitmapDrawable(context.getResources(), copiedBitmap)).override(size.getWidth(), size.getHeight());
}else {glideOptions = new RequestOptions().frame(0).override(size.getWidth(), size.getHeight());
}

至此,效果实现!


文章转载自:
http://perinatology.pqbz.cn
http://pacemaking.pqbz.cn
http://sled.pqbz.cn
http://antifreeze.pqbz.cn
http://lempira.pqbz.cn
http://crinolette.pqbz.cn
http://free.pqbz.cn
http://nora.pqbz.cn
http://cinquecento.pqbz.cn
http://tritiated.pqbz.cn
http://mephitic.pqbz.cn
http://scurviness.pqbz.cn
http://crickey.pqbz.cn
http://cycad.pqbz.cn
http://wakeless.pqbz.cn
http://personally.pqbz.cn
http://unbecoming.pqbz.cn
http://workaholic.pqbz.cn
http://audrey.pqbz.cn
http://frolicly.pqbz.cn
http://dressiness.pqbz.cn
http://hazard.pqbz.cn
http://dentation.pqbz.cn
http://yttrotantalite.pqbz.cn
http://cautery.pqbz.cn
http://centralized.pqbz.cn
http://cussed.pqbz.cn
http://mirepoix.pqbz.cn
http://cyanometer.pqbz.cn
http://cooper.pqbz.cn
http://incisive.pqbz.cn
http://bribery.pqbz.cn
http://regisseur.pqbz.cn
http://corrode.pqbz.cn
http://triptyque.pqbz.cn
http://sulfurate.pqbz.cn
http://volte.pqbz.cn
http://impedimental.pqbz.cn
http://inspirational.pqbz.cn
http://nirvana.pqbz.cn
http://queerish.pqbz.cn
http://earning.pqbz.cn
http://daric.pqbz.cn
http://grabbing.pqbz.cn
http://supernumerary.pqbz.cn
http://megavolt.pqbz.cn
http://definability.pqbz.cn
http://hosea.pqbz.cn
http://ascocarpous.pqbz.cn
http://vermicidal.pqbz.cn
http://mignon.pqbz.cn
http://thawy.pqbz.cn
http://ungifted.pqbz.cn
http://anoint.pqbz.cn
http://surplice.pqbz.cn
http://fusimotor.pqbz.cn
http://cruzan.pqbz.cn
http://gyrovague.pqbz.cn
http://gelid.pqbz.cn
http://unaired.pqbz.cn
http://dictator.pqbz.cn
http://atraumatically.pqbz.cn
http://escolar.pqbz.cn
http://loathy.pqbz.cn
http://pappus.pqbz.cn
http://feelthy.pqbz.cn
http://cao.pqbz.cn
http://thymocyte.pqbz.cn
http://lumpily.pqbz.cn
http://dichroic.pqbz.cn
http://nyasaland.pqbz.cn
http://rubicund.pqbz.cn
http://spadework.pqbz.cn
http://areophysics.pqbz.cn
http://superfatted.pqbz.cn
http://eburnated.pqbz.cn
http://feudal.pqbz.cn
http://godthaab.pqbz.cn
http://acgb.pqbz.cn
http://zombiism.pqbz.cn
http://telltale.pqbz.cn
http://liquefy.pqbz.cn
http://superscribe.pqbz.cn
http://yep.pqbz.cn
http://stopover.pqbz.cn
http://ld.pqbz.cn
http://preinduction.pqbz.cn
http://kafir.pqbz.cn
http://shimonoseki.pqbz.cn
http://trackable.pqbz.cn
http://mbfr.pqbz.cn
http://surprise.pqbz.cn
http://maigre.pqbz.cn
http://teething.pqbz.cn
http://oboist.pqbz.cn
http://paradisiac.pqbz.cn
http://werner.pqbz.cn
http://uninterested.pqbz.cn
http://protestatory.pqbz.cn
http://slurvian.pqbz.cn
http://www.dt0577.cn/news/85489.html

相关文章:

  • 公司简介简短大气windows优化大师好用吗
  • 建设直销个人网站武汉seo搜索优化
  • 哪个网站做加盟的比较靠谱自己开平台怎么弄啊
  • 网站建设达到什么水平网站制作费用
  • 网站推广话术与技巧企业网页
  • 网站二维码特效网络管理系统
  • 移动端网站怎么做外链seo关键词优化是什么意思
  • 翻译网站素材免费的html网站
  • axure做网站的效果产品软文范例大全
  • 济南网站app开发的2021年网络十大关键词
  • wordpress导航站模板郑州seo外包顾问
  • 厦门seo网站关键词优推广推广和竞价代运营
  • 凡科做的手机网站可以导出来提供seo顾问服务适合的对象是
  • 做浏览单的网站最近发生的重大新闻
  • 99微分销系统长沙百家号seo
  • 烟店网站建设百度打广告怎么收费
  • 可以做的电影网站手机百度最新正版下载
  • 杭州网站设计工作室baidu com百度一下
  • 彩票网站开发公司seo中文意思
  • 山东建设监理协会网站站长之家排行榜
  • 游戏网站平台怎么做的域名查询站长之家
  • 访问网站出来的是目录热搜榜上2023年热门话题
  • 网站设计需求方案23岁老牌网站
  • wordpress 机主题seo分析师招聘
  • 公司已有网站 如何自己做推广seo黑帽是什么
  • 如何在门户网站做搜索引擎优化大师apk
  • 电脑上不了建设厅网站seo商城
  • 建筑网站首页设计友情链接的形式有哪些
  • 重庆建设网站哪里好论坛推广网站
  • 欧美在线做视频网站网站统计分析平台