The original interview time to write proficient Glide, asked me to answer

Foreword

These days there is talk in many places to see Glide, I think the year before or the year of the interview, they also have to ask the relevant Glide, just today, taking advantage of those things in an interview Friday to chat with the Glide

  • 1, photo gallery contrast
  • 2, LRUCache principle
  • 3 Dian LruCache principle underlying implementation
  • 4, image loading principle
  • 5, to achieve their own gallery, how do?
  • 6, Glide source code parsing
  • 7, Glide what cache
  • 8, Glide how to control the size of the memory cache?
  • 9 Dian three cache principle?
  • 10 Dian how to design a larger image to load frame?

    Interview organize learning routes (Prohibition sneak O (∩_∩) O)

    Android core technologies necessary .png interview
    See the full PDF version
    (more complete project download. To be continued. Source. Graphic knowledge subsequent upload github.)
    You can click on my contact me for a full PDF

A principle Dian LRUCache

LruCacheIs a generic class, the main principle is: the most recently used objects stored in the references with a strong LinkedHashMap, when the cache is full, the least recently used objects removed from memory and provides get / put methods to complete the acquisition and add cache LruCacheis thread-safe, because the use of the synchronized keyword.

When the call put () method, the elements to the head of the list, if the list is not the element, the same size, if there is no need to call the trimToSizemethod determines whether the buffer amount exceeds the maximum, trimToSize()the method has a while (true) loop, if greater than the maximum cache size of the cache value, will continue to delete LinkedHashMapthe element squadron tail, that is accessed least until the cache size is less than the maximum cache value. When you call LruCachethe get method LinkedHashMapcalls the recordAccessmethod this element is added to the list head

Two, Glide source code parsing

1)Glide.with(context)创建了一个 RequestManager,同时实现加载图片与组件生命周期绑定:
在 Activity 上创建一个透明的 ReuqestManagerFragment 加入到 FragmentManager 中,通过添加的 Fragment 感知Activty\Fragment 的生命周期。因为添加到 Activity 中的 Fragment 会跟随Activity 的生命周期。在 RequestManagerFragment 中的相应生命周期方法中通过 liftcycle 传递给在 lifecycle 中注册的 LifecycleListener

2)RequestManager.load(url) 创建了一个 RequestBuilder<T>对象 T 可以是 Drawable 对象或是 ResourceType

3 ) RequestBuilder.into(view)-->into(glideContext.buildImageViewTarget(view, transcodeClass))返 回 的 是 一 个DrawableImageViewTarget, Target 用 来 最 终 展 示 图 片 的 ,buildImageViewTarget-->ImageViewTargetFactory.buildTarget()根据传入 class 参数不同构建不同的 Target 对象,这个 Class 是根据构建 Glide 时是否调用了 asBitmap()方法,如果调用了会构建出BitmapImageViewTarget,否则构建的是GlideDrawableImageViewTarget 对象。
-->GenericRequestBuilder.into(Target), 该 方 法 进 行 了 构 建 Request , 并 用RequestTracker.runRequest()-->GenericRequest.begin()

 Request request = buildRequest(target);
         // 构建 Request 对象, 
        target.setRequest(request);
        lifecycle.addListener(target);
 requestTracker.runRequest(request);
       // 判断 Glide 当前是不是处于暂停状态

onSizeReady()--> `Engine.load(signature, width, height, dataFetcher, loadProvider,transformation, transcoder,priority, isMemoryCacheable, diskCacheStrategy, this)

a)先构建EngineKey;

b)`loadFromCache 从 缓 存 中 获 取 EngineResource , 如 果 缓 存 中 获 取 到 cache 就 调 用`cb.onResourceReady(cached);

c)如果缓存中不存在调用loadFromActiveResources从 active中获取,如果获取到就调用cb.onResourceReady(cached);

d)如果 active 中也不存在,调用EngineJob.start(EngineRunnable), 从而调用decodeFromSource()/decodeFromCache()-->如果是调 用decodeFromSource()-->ImageVideoFetcher.loadData()-->HttpUrlFetcher()调 用HttpUrlConnection进 行 网 络 请 求 资 源 --> 得 于InputStream()后 , 调 用decodeFromSourceData()-->loadProvider.getSourceDecoder().decode() 方 法 解 码-->GifBitmapWrapperResourceDecoder.decode()-->decodeStream()先从流中读取 2 个字节判断是 GIF 还是普通图,若是 GIF 调用decodeGifWrapper()来解码,若是普通静图则调用decodeBitmapWrapper()来解码-->bitmapDecoder.decode()`

三丶Glide 使用什么缓存?

1) 内存缓存: LruResourceCache(memory)+弱引用 activeResources
Map<Key, WeakReference<EngineResource<?>>> activeResources正在使用的资源,当 acquired变量大于 0,说明图片正在使用,放到 activeResources 弱引用缓存中,经过 release()后,acquired=0,说明图片不再使用,会把它放进 LruResourceCache

2)磁盘缓存: DiskLruCache,这里分为 Source(原始图片)和 Result(转换后的图片)

第一次获取图片,肯定网络取,然后存 active\disk 中,再把图片显示出来,第二次读取相同的图片,并加载到相同大小的 imageview 中,会先从 memory 中取,没有再去 active 中获取。如果 activity 执行到 onStop 时,图片被回收,active 中的资源会被保存到memory 中,active中的资源被回收。当再次加载图片时,会从 memory 中取,再放入 active 中,并将 memory中对应的资源回收。

之所以需要 activeResources,它是一个随时可能被回收的资源,memory 的强引用频繁读写可能造成内存激增频繁 GC,而造成内存抖动。资源在使用过程中保存在 activeResources 中,而 activeResources 是弱引用,随时被系统回收,不会造成内存过多使用和泄漏。

四丶Glide 内存缓存如何控制大小?

Glide 内存缓存最大空间(maxSize)=每个进程可用最大内存0.4(低配手机是 每个进程可用最大内存0.33)

磁盘缓存大小是 250MB int DEFAULT_DISK_CACHE_SIZE = 250 1024 1024;

五丶LruCache 底层实现原理:

LruCacheLru 算法的实现就是通过 LinkedHashMap 来实现的。LinkedHashMap继承于HashMap,它使用了一个双向链表来存储 Map 中的 Entry 顺序关系,对于 get、put、remove 等操作,LinkedHashMap 除了要做 HashMap 做的事情,还做些调整 Entry 顺序链表的工作。

LruCache 中将 LinkedHashMap 的顺序设置为 LRU 顺序来实现 LRU 缓存,每次调用 get(也就是从内存缓存中取图片),则将该对象移到链表的尾端。调用 put 插入新的对象也是存储在链表尾端,这样当内存缓存达到设定的最大值时,将链表头部的对象(近期最少用到的)移除。

六丶三级缓存原理

当 Android 端需要获得数据时比如获取网络中的图片,首先从内存中查找(按键查找),内存中没有的再从磁盘文件或 sqlite 中去查找,若磁盘中也没有才通过网络获取

七丶如何设计一个大图加载框架

图片加载包含封装,解析,下载,解码,变换,缓存,显示等操作

  • 封装参数: 从指定来源,到输出结果,中间可能经历很多流程,所以第一件事就是封装参数,这些参数会贯穿整个过程;
  • 解析路径: 图片的来源有多种,格式也不尽相同,需要规范化;
  • 读取缓存: 为了减少计算,通常都会做缓存;同样的请求,从缓存中取图片(Bitmap)即可;
  • Find Files / download files: If it is a local file, can be decoded directly; if the picture is a network, you need to download;
  • Decoding: This step is one of the most complicated the whole process step, there are a lot of details, the next blog will say;
  • Transformation: After decoding Bitmap, may need to do some conversion processing (fillet, filters, etc.);
  • Cache: After obtaining the final bitmap, can be cached, taken directly to the next result request;
  • Display: displays the results, you may need to do the animation (fade-in animation, crossFade, etc.)
    The original interview time to write proficient Glide, asked me to answer
    See the full PDF version
    (complete more projects to be continued Download Source graphic knowledge subsequent upload github....)
    You can click on my contact me For a complete PDF

Guess you like

Origin blog.51cto.com/14541311/2456718