功能介绍
使用文章介绍以及和Picasso的对比分析请参考Introduction to Glide, Image Loader Library for Android, recommended by Google
由于这篇文章使用glide的老版本,因此有些使用方法可能不太一致了。
本文基于github上Glide最新代码4.0.0版本做解析。
最基本的使用方式如下:
Glide.with(this)
.asDrawable()
.load("http://i6.topit.me/6/5d/45/1131907198420455d6o.jpg")
.apply(fitCenterTransform(this))
.apply(placeholderOf(R.drawable.skyblue_logo_wechatfavorite_checked))
.into(imageView);
Glide使用了现在非常流行的流氏编码方式,方便了开发者的使用,简明、扼要。
接下来主要对上面这一段流氏操作做拆分。
Glide 主入口
这个类有点像门脸模式的统一代理入口,不过实际作用在4.0.0中很多功能都被放到后面的其他类中,此类关注的点就很少了。虽然整个libray的所有需要的组建都在这个类中,但是实际也只是一个统一初始化的地方。
RequestManager(Glide.with(…))
这个类主要用于管理和启动Glide的所有请求,可以使用activity,fragment或者连接生命周期的事件去智能的停止,启动,和重启请求。也可以检索或者通过实例化一个新的对象,或者使用静态的Glide去利用构建在Activity和Fragment生命周期处理中。它的方法跟你的Fragment和Activity的是同步的。
RequestBuilder
通用类,可以处理设置选项,并启动负载的通用资源类型。
在这个类中,主要是应用请求的很多选项(如下的选项从字面都能看出具体的用处,在ImageView控件中经常也能看到,另外之前版本可不是这么使用的):
public final class RequestOptions extends BaseRequestOptions<RequestOptions> {
private static RequestOptions skipMemoryCacheTrueOptions;
private static RequestOptions skipMemoryCacheFalseOptions;
private static RequestOptions fitCenterOptions;
private static RequestOptions centerCropOptions;
private static RequestOptions circleCropOptions;
private static RequestOptions noTransformOptions;
private static RequestOptions noAnimationOptions;
// ...省略...
}
RequestBuilder transition(TransitionOptions transitionOptions){} 这个方法主要是用于加载对象从占位符(placeholder)或者缩略图(thumbnail)到真正对象加载完成的转场动画。
RequestBuilder load(…){}多太方法中,这里可以加载很多类型的数据对象,可以是String,Uri,File,resourceId,byte[]这些。当然这些后面对应的编码方式也是不一样的。
Target into(…){}这个方法是触发Request真正启动的地方,在上边的示例中最后就是调用这个方法发起请求。
不得不说的registry域,这个域挂载了很多元件,该注册器中囊括了模块加载器(ModelLoader)、编码器(Encoder)、资源解码器(ResourceDecoder)、资源编码器(ResourceEncoder)、数据回转器(DataRewinder)、转码器(Transcoder)。这些都是Glide在对资源编解码中既是基础又是核心功能。
代码结构
这里主要列举一下一些重要的组件以及他们的结构关系:
ModelLoader
DataFetcher
Target
Resource
ResourceTransformation
Pool
Cache
Decoder
Encoder
把这些组件代码结构列举出来主要是为了让读者和使用者一目了然的看到自己需要的一些功能。
执行流程
1、根据不同版本的Fragment创建RequestManagerFragment或者SupportRequestManagerFragment,并加入到对应的FragmentManager中。这两种Fragment是不带有任何界面的,主要是用于同步生命周期。具体实现如下:
public static RequestManager with(Context context) {
RequestManagerRetriever retriever = RequestManagerRetriever.get();
return retriever.get(context);
}
// RequestManagerRetriever.get(...)
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
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, null);
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
RequestManager fragmentGet(Context context, android.app.FragmentManager fm,
android.app.Fragment parentHint) {
RequestManagerFragment current = getRequestManagerFragment(fm, parentHint);
RequestManager requestManager = current.getRequestManager();
if (requestManager == null) {
requestManager =
new RequestManager(context, current.getLifecycle(), current.getRequestManagerTreeNode());
current.setRequestManager(requestManager);
}
return requestManager;
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
RequestManagerFragment getRequestManagerFragment(
final android.app.FragmentManager fm, android.app.Fragment parentHint) {
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
current = new RequestManagerFragment();
current.setParentFragmentHint(parentHint);
pendingRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
2、创建一个RequestBuilder,并添加一个DrawableTransitionOptions类型的转场动画
public RequestBuilder<Drawable> asDrawable() {
return as(Drawable.class).transition(new DrawableTransitionOptions());
}
3、加载对象(model域)
public RequestBuilder