最近在使用Glide,遇到不少不解的问题

  • 生命周期是如何绑定的
  • 缓存策略

从官方的例子开始

    // 这里的this我们假设为Activity    Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);

with

    // with返回了一个RequestManager,RequestManager将acitivity生命周期与request绑定    // https://github.com/bumptech/glide/blob/3.0/library/src/main/java/com/bumptech/glide/Glide.java#L668    public static RequestManager with(Activity activity) {        RequestManagerRetriever retriever = RequestManagerRetriever.get();        return retriever.get(activity);    }    // https://github.com/bumptech/glide/blob/3.0/library/src/main/java/com/bumptech/glide/manager/RequestManagerRetriever.java#L120    public RequestManager get(Activity activity) {        if (Util.isOnBackgroundThread() || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {            return get(activity.getApplicationContext());        } else {            assertNotDestroyed(activity);            android.app.FragmentManager fm = activity.getFragmentManager();            return fragmentGet(activity, fm);        }    }    // https://github.com/bumptech/glide/blob/3.0/library/src/main/java/com/bumptech/glide/manager/RequestManagerRetriever.java#L167    @TargetApi(Build.VERSION_CODES.HONEYCOMB)    RequestManager fragmentGet(Context context, android.app.FragmentManager fm) {        RequestManagerFragment current = getRequestManagerFragment(fm);        RequestManager requestManager = current.getRequestManager();        if (requestManager == null) {            requestManager = new RequestManager(context,                    current.getGlideLifecycle(), current.getRequestManagerTreeNode());            current.setRequestManager(requestManager);        }        return requestManager;    }    // https://github.com/bumptech/glide/blob/3.0/library/src/main/java/com/bumptech/glide/manager/RequestManagerRetriever.java#L152    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)    RequestManagerFragment getRequestManagerFragment(final android.app.FragmentManager fm) {        RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);        if (current == null) {            current = pendingRequestManagerFragments.get(fm);            if (current == null) {                // 这里生成了一个Fragment,通过重载其生命周期回调,就可以绑定activity的生命周期                current = new RequestManagerFragment();                pendingRequestManagerFragments.put(fm, current);                fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();                handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();            }        }        return current;    }    // https://github.com/bumptech/glide/blob/3.0/library/src/main/java/com/bumptech/glide/manager/RequestManagerFragment.java    @Override    public void onStart() {        super.onStart();        lifecycle.onStart();    }    @Override    public void onStop() {        super.onStop();        lifecycle.onStop();    }    @Override    public void onDestroy() {        super.onDestroy();        lifecycle.onDestroy();    }

load

    // 开始加载图片啦,首先生成了一个DrawableTypeRequest    // https://github.com/bumptech/glide/blob/3.0/library/src/main/java/com/bumptech/glide/RequestManager.java#L283    public DrawableTypeRequest load(String string) {        return (DrawableTypeRequest) fromString().load(string);    }    // https://github.com/bumptech/glide/blob/3.0/library/src/main/java/com/bumptech/glide/RequestManager.java#L303    public DrawableTypeRequest fromString() {        return loadGeneric(String.class);    }    // https://github.com/bumptech/glide/blob/3.0/library/src/main/java/com/bumptech/glide/RequestManager.java#L624    private  DrawableTypeRequest loadGeneric(Class modelClass) {        ModelLoader streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);        ModelLoader fileDescriptorModelLoader =                Glide.buildFileDescriptorModelLoader(modelClass, context);        if (modelClass != null && streamModelLoader == null && fileDescriptorModelLoader == null) {            throw new IllegalArgumentException("Unknown type " + modelClass + ". You must provide a Model of a type for"                    + " which there is a registered ModelLoader, if you are using a custom model, you must first call"                    + " Glide#register with a ModelLoaderFactory for your custom model class");        }        return optionsApplier.apply(                new DrawableTypeRequest(modelClass, streamModelLoader, fileDescriptorModelLoader, context,                        glide, requestTracker, lifecycle, optionsApplier));    }    // https://github.com/bumptech/glide/blob/3.0/library/src/main/java/com/bumptech/glide/DrawableTypeRequest.java#L30    // DrawableTypeRequest继承自DrawableRequestBuilder,通过optionsApplier.apply可以调整加载参数    public class DrawableTypeRequest<ModelType> extends DrawableRequestBuilder<ModelType> implements DownloadOptions {...}

into

    // https://github.com/bumptech/glide/blob/3.0/library/src/main/java/com/bumptech/glide/DrawableRequestBuilder.java#L456    // into正式开始加载图片,包括下载缓存显示    @Override        public Target into(ImageView view) {        return super.into(view);    }    // https://github.com/bumptech/glide/blob/3.0/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java#L682    public Target into(ImageView view) {        Util.assertMainThread();        if (view == null) {            throw new IllegalArgumentException("You must pass in a non null View");        }        if (!isTransformationSet && view.getScaleType() != null) {            switch (view.getScaleType()) {                case CENTER_CROP:                    applyCenterCrop();                    break;                case FIT_CENTER:                case FIT_START:                case FIT_END:                    applyFitCenter();                    break;                //$CASES-OMITTED$                default:                    // Do nothing.            }        }        // 这里buildImageViewTarget返回了ImageViewTarget(确切来说是子类),封装了一个ImageView,在request结束后会设置对应的image        return into(glide.buildImageViewTarget(view, transcodeClass));    }    // https://github.com/bumptech/glide/blob/3.0/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java#L648    public > Y into(Y target) {        Util.assertMainThread();        if (target == null) {            throw new IllegalArgumentException("You must pass in a non null Target");        }        if (!isModelSet) {            throw new IllegalArgumentException("You must first set a model (try #load())");        }        Request previous = target.getRequest();        if (previous != null) {            previous.clear();            requestTracker.removeRequest(previous);            previous.recycle();        }        // 这里的buildRequest最后会返回一个GenericRequest        // (代码很长,通过窥屏知道的http://blog.csdn.net/guolin_blog/article/details/53939176/)        Request request = buildRequest(target);        target.setRequest(request);        lifecycle.addListener(target);        requestTracker.runRequest(request);        return target;    }    // https://github.com/bumptech/glide/blob/3.0/library/src/main/java/com/bumptech/glide/manager/RequestTracker.java#L34    public void runRequest(Request request) {        requests.add(request);        if (!isPaused) {            // 请求从这里开始发起,搜索内存,磁盘缓存,及网络请求            request.begin();        } else {            pendingRequests.add(request);        }    }    // https://github.com/bumptech/glide/blob/3.0/library/src/main/java/com/bumptech/glide/request/GenericRequest.java#L261    @Override    public void begin() {        startTime = LogTime.getLogTime();        if (model == null) {            onException(null);            return;        }        status = Status.WAITING_FOR_SIZE;        if (Util.isValidDimensions(overrideWidth, overrideHeight)) {            // 真实的请求从这里开始,这个名字好坑            onSizeReady(overrideWidth, overrideHeight);        } else {            target.getSize(this);        }        if (!isComplete() && !isFailed() && canNotifyStatusChanged()) {            // 设置占位图            target.onLoadStarted(getPlaceholderDrawable());        }        if (Log.isLoggable(TAG, Log.VERBOSE)) {            logV("finished run method in " + LogTime.getElapsedMillis(startTime));        }    }    // https://github.com/bumptech/glide/blob/3.0/library/src/main/java/com/bumptech/glide/request/GenericRequest.java#L425    @Override    public void onSizeReady(int width, int height) {        if (Log.isLoggable(TAG, Log.VERBOSE)) {            logV("Got onSizeReady in " + LogTime.getElapsedMillis(startTime));        }        if (status != Status.WAITING_FOR_SIZE) {            return;        }        status = Status.RUNNING;        width = Math.round(sizeMultiplier * width);        height = Math.round(sizeMultiplier * height);        ModelLoader modelLoader = loadProvider.getModelLoader();        final DataFetcher dataFetcher = modelLoader.getResourceFetcher(model, width, height);        if (dataFetcher == null) {            onException(new Exception("Failed to load model: \'" + model + "\'"));            return;        }        ResourceTranscoder transcoder = loadProvider.getTranscoder();        if (Log.isLoggable(TAG, Log.VERBOSE)) {            logV("finished setup for calling load in " + LogTime.getElapsedMillis(startTime));        }        loadedFromMemoryCache = true;        // 这里进入engine的加载流程        loadStatus = engine.load(signature, width, height, dataFetcher, loadProvider, transformation, transcoder,                priority, isMemoryCacheable, diskCacheStrategy, this);        loadedFromMemoryCache = resource != null;        if (Log.isLoggable(TAG, Log.VERBOSE)) {            logV("finished onSizeReady in " + LogTime.getElapsedMillis(startTime));        }    }    // https://github.com/bumptech/glide/blob/3.0/library/src/main/java/com/bumptech/glide/load/engine/Engine.java    // 简单看下,主要是查缓存及网络请求了    public  LoadStatus load(Key signature, int width, int height, DataFetcher fetcher,            DataLoadProvider loadProvider, Transformation transformation, ResourceTranscoder transcoder,            Priority priority, boolean isMemoryCacheable, DiskCacheStrategy diskCacheStrategy, ResourceCallback cb) {        Util.assertMainThread();        long startTime = LogTime.getLogTime();        final String id = fetcher.getId();        EngineKey key = keyFactory.buildKey(id, signature, width, height, loadProvider.getCacheDecoder(),                loadProvider.getSourceDecoder(), transformation, loadProvider.getEncoder(),                transcoder, loadProvider.getSourceEncoder());        EngineResource<?> 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;        }        EngineResource<?> 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;        }        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);        if (Log.isLoggable(TAG, Log.VERBOSE)) {            logWithTimeAndKey("Started new load", startTime, key);        }        return new LoadStatus(cb, engineJob);    }

更多相关文章

  1. IntentService源码分析
  2. 阿里Android(安卓)26条规范经验及优化
  3. Android中存储目录
  4. Android网络通信库Volley简介
  5. 第五章 网络 之 Android网络知识&框架
  6. android开发,加载网络图片时 报错android.os.NetworkOnMainThread
  7. Android(安卓)Volley框架详解
  8. Android使用glide加载gif动画设置播放次数
  9. urlConn.setRequestProperty是做什么的以及作用

随机推荐

  1. android语音即时通讯之录音、播放功能实
  2. Android9.0万年历毕业设计H5小应用webvie
  3. 杂记-Android(安卓)Studio 2.2 新功能
  4. TTF字体库系列文章1 —— Android使用ttf
  5. 这篇 Widget 秘籍,让你的 iPhone 下拉通知
  6. 解密:为什么Android机没有iPhone流畅呢?
  7. Android常见的八种导致 APP 内存泄漏的问
  8. Android蓝牙完全学习手册
  9. Android监听ScrollView的滚动事件
  10. Android(安卓)阅读 Office 文档,所有你能