资讯专栏INFORMATION COLUMN

Glide的源码分析(二) 2.2

Jason / 1922人阅读

摘要:从网络加载图片加载从加载从网络加载从加载具体的方法实现接口的类以后再做分析,而从网络加载两步从网络获取数据处理数据。

4.从网络加载

        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 decodeJob = new DecodeJob(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);

EngineRunnable.java:

    @Override
    public void run() {
        if (isCancelled) {
            return;
        }

        Exception exception = null;
        Resource resource = null;
        try {
            resource = decode();
        } catch (Exception e) {
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                Log.v(TAG, "Exception decoding", e);
            }
            exception = e;
        }

        if (isCancelled) {
            if (resource != null) {
                resource.recycle();
            }
            return;
        }

        if (resource == null) {
            onLoadFailed(exception);
        } else {
            onLoadComplete(resource);
        }
    }
    private Resource decode() throws Exception {
        if (isDecodingFromCache()) {
            return decodeFromCache();
        } else {
            return decodeFromSource();
        }
    }

图片加载:
1.从disk加载
2.从网络加载
从disk加载
DecodeJob.java:

   private Resource loadFromCache(Key key) throws IOException {
        File cacheFile = diskCacheProvider.getDiskCache().get(key);
        if (cacheFile == null) {
            return null;
        }

        Resource result = null;
        try {
            result = loadProvider.getCacheDecoder().decode(cacheFile, width, height);
        } finally {
            if (result == null) {
                diskCacheProvider.getDiskCache().delete(key);
            }
        }
        return result;
    }

具体decode的方法 实现ResourceDecoder接口的类

以后再做分析,而从网络加载

Decoder.java:

    private Resource decodeSource() throws Exception {
        Resource decoded = null;
        try {
            long startTime = LogTime.getLogTime();
            final A data = fetcher.loadData(priority);
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                logWithTimeAndKey("Fetched data", startTime);
            }
            if (isCancelled) {
                return null;
            }
            decoded = decodeFromSourceData(data);
        } finally {
            fetcher.cleanup();
        }
        return decoded;
    }

两步:
1.从网络获取数据;
2.处理数据。
HttpUrlFetcher.java:

    private InputStream loadDataWithRedirects(URL url, int redirects, URL lastUrl, Map headers)
            throws IOException {
        if (redirects >= MAXIMUM_REDIRECTS) {
            throw new IOException("Too many (> " + MAXIMUM_REDIRECTS + ") redirects!");
        } else {
            // Comparing the URLs using .equals performs additional network I/O and is generally broken.
            // See http://michaelscharf.blogspot.com/2006/11/javaneturlequals-and-hashcode-make.html.
            try {
                if (lastUrl != null && url.toURI().equals(lastUrl.toURI())) {
                    throw new IOException("In re-direct loop");
                }
            } catch (URISyntaxException e) {
                // Do nothing, this is best effort.
            }
        }
        urlConnection = connectionFactory.build(url);
        for (Map.Entry headerEntry : headers.entrySet()) {
          urlConnection.addRequestProperty(headerEntry.getKey(), headerEntry.getValue());
        }
        urlConnection.setConnectTimeout(2500);
        urlConnection.setReadTimeout(2500);
        urlConnection.setUseCaches(false);
        urlConnection.setDoInput(true);

        // Connect explicitly to avoid errors in decoders if connection fails.
        urlConnection.connect();
        if (isCancelled) {
            return null;
        }
        final int statusCode = urlConnection.getResponseCode();
        if (statusCode / 100 == 2) {
            return getStreamForSuccessfulRequest(urlConnection);
        } else if (statusCode / 100 == 3) {
            String redirectUrlString = urlConnection.getHeaderField("Location");
            if (TextUtils.isEmpty(redirectUrlString)) {
                throw new IOException("Received empty or null redirect url");
            }
            URL redirectUrl = new URL(url, redirectUrlString);
            return loadDataWithRedirects(redirectUrl, redirects + 1, url, headers);
        } else {
            if (statusCode == -1) {
                throw new IOException("Unable to retrieve response code from HttpUrlConnection.");
            }
            throw new IOException("Request failed " + statusCode + ": " + urlConnection.getResponseMessage());
        }
    }

3XX重定向

   URL redirectUrl = new URL(url, redirectUrlString);
   return loadDataWithRedirects(redirectUrl, redirects + 1, url, headers);

处理数据:

 private Resource decodeFromSourceData(A data) throws IOException {
        final Resource decoded;
        if (diskCacheStrategy.cacheSource()) {
            decoded = cacheAndDecodeSourceData(data);
        } else {
            long startTime = LogTime.getLogTime();
            decoded = loadProvider.getSourceDecoder().decode(data, width, height);
            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                logWithTimeAndKey("Decoded from source", startTime);
            }
        }
        return decoded;
    }

具体decode的方法 实现ResourceDecoder接口的类

EngineJob.java:

    private final ExecutorService diskCacheService;
    
    public void start(EngineRunnable engineRunnable) {
        this.engineRunnable = engineRunnable;
        future = diskCacheService.submit(engineRunnable);
    }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/14095.html

相关文章

  • Glide源码分析() 2.2

    摘要:从网络加载图片加载从加载从网络加载从加载具体的方法实现接口的类以后再做分析,而从网络加载两步从网络获取数据处理数据。 4.从网络加载 EngineJob current = jobs.get(key); if (current != null) { current.addCallback(cb); if (...

    warkiz 评论0 收藏0
  • Glide源码分析() 2.1

    摘要:请求处理将要加载的资源放入到其中这段代码涉及属性暂且放到一边,而这段代码表明当同一个上要加载两个资源,不论资源是否一致,将前一个资源请求取消创建新的资源请求绑定有两个列表,用来存储所有的和暂停掉的加载图片的过程开启资源请求加载图片分几步 2.Request请求处理 DrawableRequestBuilder.into(ImageView)RequestManager.load将要加载...

    wpw 评论0 收藏0
  • Glide源码分析() 2.1

    摘要:请求处理将要加载的资源放入到其中这段代码涉及属性暂且放到一边,而这段代码表明当同一个上要加载两个资源,不论资源是否一致,将前一个资源请求取消创建新的资源请求绑定有两个列表,用来存储所有的和暂停掉的加载图片的过程开启资源请求加载图片分几步 2.Request请求处理 DrawableRequestBuilder.into(ImageView)RequestManager.load将要加载...

    yuxue 评论0 收藏0
  • 安卓新建项目 - 收藏集 - 掘金

    摘要:经也要热更新掘金本文同步自的地方酒馆好久没写博客了。好了,说了这么多还没见到图从零开始搭建一个项目第章掘金鸡汤成功其实很简单,定下一个合理的计划,然后坚持按照计划执行。 用RecyclerView展示错误和空白界面 附加详情界面实践-MultiItem进阶 | 掘金技术征文 - 掘金前言 本文是MultiItem系列的进阶文章,讲解如何展示空白、错误等状态页,这个功能比较常用,实现的思...

    Sanchi 评论0 收藏0
  • Glide 这样用,更省内存!!!

    摘要:在其它情况的回调中,直接调用方法来交给处理内存情况。其它在部分智能电视和盒子上,拿到的尺寸会小,因为没有计算或者的高度,这些都是经验之谈。在其中,记录的这个值,反应当前的内存级别,在使用的时候,通过裁剪出一个符合当前内存环境的尺寸。 showImg(https://segmentfault.com/img/remote/1460000011423894?w=500&h=332); 一、...

    cheukyin 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<