Glide使用及源码分析

目录

1.简介

2.使用

3.分析

1)with()

a.get(Context context)

b.get(Activity activity)

2)load()

a.DrawableTypeRequest   

b.fromString()

c.load(string)

3)into()

a)applyCenterCrop()

b)glide.buildImageViewTarget(view, transcodeClass)

c)into()


1.简介

①Model(本地、网络图等)  ----经过ModelLoader加载数据---->   

②拿到原始数据Data   ----Decoder资源解码----> 

③得到解码后资源Resource  ----Transform裁剪等转换操作---->

④变成TransformedResource  ----图像进行Transcode转码操作---->

⑤变成TranscodedResource   -------->设置到Target,即ImageView上

2.使用

依赖:compile 'com.github.bumptech.glide:glide:3.7.0'

        Glide.with(getApplicationContext())//目标context->决定加载图片的生命周期
                .load(R.mipmap.draw_img)//图片资源
                .placeholder(R.mipmap.ic_launcher)//预览图
                .error(R.mipmap.ic_launcher)//加载失败展示图
                .override(300,300) //指定图片的大小,避免内存浪费
                .fitCenter() //缩放类型 可能不填满控件,留白
                .centerCrop()//缩放类型 可能不完全显示,裁剪超出控件部分
                .skipMemoryCache(true)//跳过内存缓存 默认使用内存缓存
                .crossFade(500)//设置渐变式显示的时间
                .diskCacheStrategy(DiskCacheStrategy.ALL)//缓存所有版本的图像
                .diskCacheStrategy(DiskCacheStrategy.NONE)//跳过磁盘缓存
                .diskCacheStrategy(DiskCacheStrategy.SOURCE)//只缓存原来的全分辨率的图像
                .diskCacheStrategy(DiskCacheStrategy.RESULT)//只缓存最后处理过的图像
                .priority(Priority.HIGH)//加载优先级
                .into(imageView);//目标控件

3.分析

1)with()

    public static RequestManager with(Context context) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();
        return retriever.get(context);
    }
   
    public static RequestManager with(Activity activity) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();
        return retriever.get(activity);
    }

    public static RequestManager with(FragmentActivity activity) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();
        return retriever.get(activity);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public static RequestManager with(android.app.Fragment fragment) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();
        return retriever.get(fragment);
    }

    public static RequestManager with(Fragment fragment) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();
        return retriever.get(fragment);
    }

看到可传入的参数可以为5种类型,主要是方便绑定不同的生命周期,来控制图片的加载和销毁的时机等。

先看看第一个参数为Context的:

    public static RequestManager with(Context context) {
        RequestManagerRetriever retriever = RequestManagerRetriever.get();
        return retriever.get(context);
    }

RequestManagerRetriever,其作用主要用于生产RequestManager:

public class RequestManagerRetriever implements Handler.Callback {
    
    private volatile RequestManager applicationManager;

    ...}

我们可以把RequestManager暂时理解为处理图片加载请求的管理者。

a.get(Context context)

当RequestManagerRetriever创建好了后,调用了它的get方法:

public class RequestManagerRetriever implements Handler.Callback {

    public RequestManager get(Context context) {
      //入参判空
      if (context == null) {
       throw new IllegalArgumentException("You cannot start a load on a null Context");
      } 
      //是否在主线程 类型判断 
      else if (Util.isOnMainThread() && !(context instanceof Application)) {
            if (context instanceof FragmentActivity) {
                return get((FragmentActivity) context);
            } else if (context instanceof Activity) {
                return get((Activity) context);
            } else if (context instanceof ContextWrapper) {
                return get(((ContextWrapper) context).getBaseContext());
            }
      }
      //当不满足在主线程  且  类型为Application,则调用如下方法
      return getApplicationManager(context);
    }

    //当不满足在主线程  且  类型为Application  获取需要的RequestManager 
    private RequestManager getApplicationManager(Context context) {
        //双重锁单例  初始化
        if (applicationManager == null) {
          synchronized (this) {
             if (applicationManager == null) {
                //初始化RequestManager,并返回
                applicationManager = new RequestManager(
                        context.getApplicationContext(),
                        new ApplicationLifecycle(), 
                        new EmptyRequestManagerTreeNode());
                }
            }
        }
        return applicationManager;
    }

...
}

b.get(Activity activity)

上面代码描述了入参为Context的情形,再来看看入参为Activity的情形:

public class RequestManagerRetriever implements Handler.Callback {

    ...

    public RequestManager get(Activity activity) {
        //为后台线程,切版本小于11
        if (Util.isOnBackgroundThread() || 
            Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {

            //调用的get方法,就是上方讲解过的,入参为Context的get方法
            return get(activity.getApplicationContext());

        } else {
            //下方->判断act是否销毁
            assertNotDestroyed(activity);
            //注意这里通过activity对象拿到fra的管理
            android.app.FragmentManager fm = activity.getFragmentManager();
            //通过fragmentGet获取RequestManager 
            return fragmentGet(activity, fm);
        }
    }

    ...
    //判断activity是否销毁,销毁则抛出异常
    private static void assertNotDestroyed(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && activity.isDestroyed()) {
            throw new IllegalArgumentException("You cannot start a load for a destroyed activity");
        }
    }

    ...
}

看看fragmentGet(activity, fm):

RequestManager fragmentGet(Context context, android.app.FragmentManager fm) {
   //获取RequestManager  
   //通过这两行,可以发现RequestManagerFragment是和RequestManager绑定的,即一一对应
   RequestManagerFragment current = getRequestManagerFragment(fm);
   RequestManager requestManager = current.getRequestManager();
     
        if (requestManager == null) {
            //创建RequestManager
            requestManager = new RequestManager(context, 
                current.getLifecycle(), 
                current.getRequestManagerTreeNode());
            //手动绑定RequestManager和无界面的fragment,即RequestManagerFragment 
            current.setRequestManager(requestManager);
        }
        return requestManager;
    }

RequestManagerFragment属于一种无界面的fragment,因为glide无法直接监听Activity的生命周期,所以选择通过其绑定RequestManager,从而去将图片加载等操作绑定到Activity的生命周期上。进入RequestManagerFragment:

/**
 * can be used to start, stop and manage Glide requests started for targets the fragment or             
 * activity this fragment is a 
 */
//官方注释很明确,提示RequestManagerFragment管理Glide请求的开始和结束
public class RequestManagerFragment extends Fragment {
    
    //实现Lifecycle接口,
    private final ActivityFragmentLifecycle lifecycle;
    
    //调用ActivityFragmentLifecycle的方法,去监听activity的生命周期
    @Override
    public void onStart() {
        super.onStart();
        lifecycle.onStart();
    }

    @Override
    public void onStop() {
        super.onStop();
        lifecycle.onStop();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        lifecycle.onDestroy();
    }
}

 看看ActivityFragmentLifecycle:

class ActivityFragmentLifecycle implements Lifecycle {
    private final Set lifecycleListeners =
            Collections.newSetFromMap(new WeakHashMap());
    private boolean isStarted;
    private boolean isDestroyed;

    ...

    //作用:监听activity的onStart  onStop  onDestroy
    void onStart() {
       isStarted = true;
       for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
            lifecycleListener.onStart();
        }
    }

    void onStop() {
       isStarted = false;
       for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
            lifecycleListener.onStop();
        }
    }

    void onDestroy() {
       isDestroyed = true;
       for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
            lifecycleListener.onDestroy();
        }
    }
}

2)load()

load支持多种图片来源:

Glide使用及源码分析_第1张图片

看看load(String):

    public DrawableTypeRequest load(String string) {
        return (DrawableTypeRequest) fromString().load(string);
    }

分成3部分:DrawableTypeRequest   +   fromString()   +   load(string)

a.DrawableTypeRequest   

继承关系如下:

先看看DrawableTypeRequest

/**
 * A class for creating a load request that loads either an animated GIF drawable or a     
 * Bitmap drawable directly, or
 * adds an ResourceTranscoder to transcode the data into a
 * resource type other than a Drawable
 */
//翻译:用于创建加载请求的类,该请求加载动画GIF drawable或位图可直接绘制,或添加一个
//ResourceTranscoder来将数据转换为资源类型(Drawable除外)
public class DrawableTypeRequest 
        extends DrawableRequestBuilder 
        implements DownloadOptions {

    //强制指定加载静态图片   返回BitmapTypeRequest
    public BitmapTypeRequest asBitmap() {
        return optionsApplier.apply(new BitmapTypeRequest(this,                         
streamModelLoader,fileDescriptorModelLoader, optionsApplier));
    }

    //强制指定加载动态gif图片  返回GifTypeRequest
     public GifTypeRequest asGif() {
        return optionsApplier.apply(new GifTypeRequest(this, 
            streamModelLoader, optionsApplier));
    }
}

再看看最终的GenericRequestBuilder:

public class GenericRequestBuilder implements Cloneable {

protected final Class modelClass;
    
    protected final Context context;
    protected final Glide glide;
    protected final Class transcodeClass;
    private int placeholderId;//预览
    private int errorId;//失败
    private Priority priority = null;//优先级
    private int overrideHeight = -1;//重写宽高
    private int overrideWidth = -1;
    protected final RequestTracker requestTracker;//请求追踪器,跟踪图片请求周期
    protected final Lifecycle lifecycle;
    private DiskCacheStrategy diskCacheStrategy = DiskCacheStrategy.RESULT;//缓存策略
    private ChildLoadProvider loadProvider;
    ...


}

b.fromString()

    public DrawableTypeRequest fromString() {
        return loadGeneric(String.class);
    }
private  DrawableTypeRequest loadGeneric(Class modelClass) {    
  //创建2个modelloader  用来加载model(图片资源)
  ModelLoader streamModelLoader = Glide.buildStreamModelLoader(modelClass, context);
        ModelLoader fileDescriptorModelLoader =
                Glide.buildFileDescriptorModelLoader(modelClass, context);
        ...

        //创建DrawableTypeRequest
        //参数基本都在父类GenericRequestBuilder中
        return optionsApplier.apply(
                new DrawableTypeRequest(modelClass, 
                                           streamModelLoader, 
                                           fileDescriptorModelLoader, 
                                           context,
                                           glide,
                                           requestTracker,
                                           lifecycle,
                                           optionsApplier));
    }

c.load(string)

    @Override
    public DrawableRequestBuilder load(ModelType model) {
        super.load(model);
        return this;
    }

进入super.load(model):

public class GenericRequestBuilder implements Cloneable {

    public GenericRequestBuilder
 load(ModelType model) {
        //赋值操作
        this.model = model;
        isModelSet = true;
        return this;
    }

...
}

可以发现load(string)方法其实,也是在做一些初始化赋值的操作。同时拿到了图片请求的管理DrawableRequestBuilder。

3)into()

    @Override
    public Target into(ImageView view) {
        return super.into(view);
    }

进入父类into():

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;
                default:
                    // Do nothing.
            }
        }
        //最终生成imagetarget
        return into(glide.buildImageViewTarget(view, transcodeClass));
    }

a)applyCenterCrop()

其最终实现操作的类有3个:

DrawableRequestBuilder

BitmapRequestBuilder

GifRequestBuilder

看看DrawableRequestBuilder的实现操作:

//第一步
@Override
void applyCenterCrop() {
     centerCrop();
}

//第二步
public DrawableRequestBuilder centerCrop() {
        //getDrawableCenterCrop()初始化Transformation
        return transform(glide.getDrawableCenterCrop());
}

//第三步
@Override
public DrawableRequestBuilder transform
(Transformation... transformation) {
        super.transform(transformation);
}

//第四步  初始化Transformation
GenericRequestBuilder 
transform(
   Transformation... transformations) {
        isTransformationSet = true;
        if (transformations.length == 1) {
            transformation = transformations[0];
        } else {
            transformation = new MultiTransformation(transformations);
        }

        return this;
    }

b)glide.buildImageViewTarget(view, transcodeClass)

//第一步
 Target buildImageViewTarget(ImageView imageView, Class transcodedClass) {
        return imageViewTargetFactory.buildTarget(imageView, transcodedClass);
    }

//第二步
 public  Target buildTarget(ImageView view, Class clazz) {
            //加载gif
        if (GlideDrawable.class.isAssignableFrom(clazz)) {
            return (Target) new GlideDrawableImageViewTarget(view);
        } 
            //调用asbitmap的加载
        else if (Bitmap.class.equals(clazz)) {
            return (Target) new BitmapImageViewTarget(view);
        } 
            //加载drawable
        else if (Drawable.class.isAssignableFrom(clazz)) {
            return (Target) new DrawableImageViewTarget(view);
        } else {
            throw new IllegalArgumentException("Unhandled class: " + clazz
                    + ", try .as*(Class).transcode(ResourceTranscoder)");
        }
    }

看看方法返回的Target类和其继承的LifecycleListener: 

public interface Target extends LifecycleListener {
   
    int SIZE_ORIGINAL = Integer.MIN_VALUE;
   
    void onLoadStarted(Drawable placeholder);

    void onLoadFailed(Exception e, Drawable errorDrawable);

    void getSize(SizeReadyCallback cb);
  
    void setRequest(Request request);

    Request getRequest();
}



public interface LifecycleListener {
   
    void onStart();
   
    void onStop();

    void onDestroy();
}

找到target实现类ImageViewTarget:

public abstract class ImageViewTarget extends 
ViewTarget implements GlideAnimation.ViewAdapter {

    public ImageViewTarget(ImageView view) {
        super(view);
    }

    @Override
    public Drawable getCurrentDrawable() {
        return view.getDrawable();
    }

    @Override
    public void setDrawable(Drawable drawable) {
        view.setImageDrawable(drawable);
    }

    //显示占位图片
    @Override
    public void onLoadStarted(Drawable placeholder) {
        view.setImageDrawable(placeholder);
    }

    //显示占位图片
    @Override
    public void onLoadFailed(Exception e, Drawable errorDrawable) {
        view.setImageDrawable(errorDrawable);
    }

    //显示占位图片
    @Override
    public void onLoadCleared(Drawable placeholder) {
        view.setImageDrawable(placeholder);
    }

    @Override
    public void onResourceReady(Z resource, GlideAnimation glideAnimation) {
        if (glideAnimation == null || !glideAnimation.animate(resource, this)) {
            setResource(resource);
        }
    }

    //抽象的setResource()
    protected abstract void setResource(Z resource);
}

抽象的setResource,是因为加载的资源有多种。

可以看到抽象方法的实现类有3个:

1.BitmapImageViewTarget

public class BitmapImageViewTarget extends ImageViewTarget {
    public BitmapImageViewTarget(ImageView view) {
        super(view);
    }

    //设置bitmap
    @Override
    protected void setResource(Bitmap resource) {
        view.setImageBitmap(resource);
    }
}

2.DrawableImageViewTarget

public class DrawableImageViewTarget extends ImageViewTarget {
    public DrawableImageViewTarget(ImageView view) {
        super(view);
    }

    //加载drawable
    @Override
    protected void setResource(Drawable resource) {
       view.setImageDrawable(resource);
    }
}

3.GlideDrawableImageViewTarget

    @Override
    protected void setResource(GlideDrawable resource) {
        view.setImageDrawable(resource);
    }

现在可以知道glide.buildImageViewTarget(view, transcodeClass),是返回了target,且target内部封装了图片加载过程。

c)into()

    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,request是通过settag绑定到target的
        Request previous = target.getRequest();
        //对旧的已绑定的target的request,进行清空删除
        if (previous != null) {
            previous.clear();
            requestTracker.removeRequest(previous);
            previous.recycle();
        }

        //新建request
        Request request = buildRequest(target);
        //通过settag将request和target绑定
        target.setRequest(request);
        //设置监听
        lifecycle.addListener(target);
        //请求跟踪器,执行加载request请求
        requestTracker.runRequest(request);
        return target;
    }

重点看runRequest(),执行request请求的方法:

public void runRequest(Request request) {
        requests.add(request);
        if (!isPaused) {
            request.begin();
        } else {
            pendingRequests.add(request);
        }
    }

进入request.begin(),查看GenericRequest类的实现:

@Override
    public void begin() {
        startTime = LogTime.getLogTime();
        if (model == null) {
            onException(null);
            return;
        }
        status = Status.WAITING_FOR_SIZE;
        //是否指定大小,比如调用过.override(300,300) 
        if (Util.isValidDimensions(overrideWidth, overrideHeight)) {
            onSizeReady(overrideWidth, overrideHeight);
        } else {
            //计算出宽高,之后也会回到onSizeReady()方法
            target.getSize(this);
        }
        //显示占位图片
        if (!isComplete() && !isFailed() && canNotifyStatusChanged()) {
            target.onLoadStarted(getPlaceholderDrawable());
        }
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            logV("finished run method in " + LogTime.getElapsedMillis(startTime));
        }
    }

看看onSizeReady():

  @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;
        //加载过程
        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));
   }
  }

进入重点加载图片的方法engine.load():

    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();
        //获取图片加载的标识  如果加载网络图片,则是图片url
        final String id = fetcher.getId();
        //EngineKey可以理解为glide缓存图片的key
        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为带弱引用的map
        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);
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(android源码分析)