fred-ye / summary

my blog
43 stars 9 forks source link

[Android] Universal-Image-Loader的主逻辑分析 #55

Open fred-ye opened 8 years ago

fred-ye commented 8 years ago

Universal-Image-Loader的主逻辑分析

从入口ImageLoader.diaplayImage()开始看,流程如下:

engine

需要注意的几点

两个复杂的流程在LoadingAndDisplayTaskProcessAndDisplayImageTask, 这两个类都实现了Runnable接口,ProcessAndDisplayImageTask实现较简单,不进行具体分析,接着看一下LoadingAndDisplayTask

loadanddisplay

需要注意的几点

这张图中的主逻辑在于tryLoadBitmap这个方法。这里不画流程图,直接上代码,在代码上加上注释

private Bitmap tryLoadBitmap() throws TaskCancelledException {
    Bitmap bitmap = null;
    try {
        File imageFile = configuration.diskCache.get(uri); //检测DiskCache中是否有
        if (imageFile != null && imageFile.exists() && imageFile.length() > 0) {
            L.d(LOG_LOAD_IMAGE_FROM_DISK_CACHE, memoryCacheKey);
            loadedFrom = LoadedFrom.DISC_CACHE;

            checkTaskNotActual();
            bitmap = decodeImage(Scheme.FILE.wrap(imageFile.getAbsolutePath()));
        }
        if (bitmap == null || bitmap.getWidth() <= 0 || bitmap.getHeight() <= 0) {
            L.d(LOG_LOAD_IMAGE_FROM_NETWORK, memoryCacheKey);
            loadedFrom = LoadedFrom.NETWORK;

            String imageUriForDecoding = uri; //   此时是网络路径
            //如果需要缓存到Disk, 同时执行download成功。 tryCacheImageOnDisk中会去下载图片
            if (options.isCacheOnDisk() && tryCacheImageOnDisk()) {
                imageFile = configuration.diskCache.get(uri);
                if (imageFile != null) {
                    //此时是下载完成后的本地路径
                    imageUriForDecoding = Scheme.FILE.wrap(imageFile.getAbsolutePath());
                }
            }

            checkTaskNotActual();
            //如果上面的下载还没有成功,此处还有一次机会去下载, 此时的下载不会去做缓存
            bitmap = decodeImage(imageUriForDecoding);

            if (bitmap == null || bitmap.getWidth() <= 0 || bitmap.getHeight() <= 0) {
                fireFailEvent(FailType.DECODING_ERROR, null);
            }
        }
    } catch (IllegalStateException e) {
        fireFailEvent(FailType.NETWORK_DENIED, null);
    } catch (TaskCancelledException e) {
        throw e;
    } catch (IOException e) {
        L.e(e);
        fireFailEvent(FailType.IO_ERROR, e);
    } catch (OutOfMemoryError e) {
        L.e(e);
        fireFailEvent(FailType.OUT_OF_MEMORY, e);
    } catch (Throwable e) {
        L.e(e);
        fireFailEvent(FailType.UNKNOWN, e);
    }
    return bitmap;
}