之前大致把ImagePipeline的配置和底层实现都讲了一下,这一篇来重点讲一下我们在发送图片请求的时候是怎么把请求传给ImagePipeline的,以及我们如何自己直接对ImagePipeline实例进行请求,内存管理等操作。
SimpleDraweeView中ImagePipeline的调用
在第一篇的时候,我们当时只需要对SimpleDraweeView进行setImageURI()方法,setController()方法之后,都能够成功发起图片请求,那底层是怎么实现的呢。先来看一下SimpleDraweeView中的相关代码:
/**
* Displays an image given by the uri.
*
* @param uri uri of the image
* @undeprecate
*/
@Override
public void setImageURI(Uri uri) {
setImageURI(uri, null);
}
/**
* Displays an image given by the uri string.
*
* @param uriString uri string of the image
*/
public void setImageURI(@Nullable String uriString) {
setImageURI(uriString, null);
}
/**
* Displays an image given by the uri.
*
* @param uri uri of the image
* @param callerContext caller context
*/
//最终都会执行该方法
public void setImageURI(Uri uri, @Nullable Object callerContext) {
DraweeController controller = mSimpleDraweeControllerBuilder
.setCallerContext(callerContext)
.setUri(uri)
.setOldController(getController())
.build();
//所有setImageURI最终调用方法
setController(controller);
}
/**
* Displays an image given by the uri string.
*
* @param uriString uri string of the image
* @param callerContext caller context
*/
public void setImageURI(@Nullable String uriString, @Nullable Object callerContext) {
Uri uri = (uriString != null) ? Uri.parse(uriString) : null;
setImageURI(uri, callerContext);
}
可以看出,不管用的是哪一个重载的setImageURI,最终都是会调用到同一个方法中,而该方法中又会执行setController()方法。那我们来看一下setController()方法,所以我们用不管setImageURI()还是setController()最终都是殊途同归。setController()在父类DraweeView()中。DraweeView是一个继承于ImageView的子类:
private DraweeHolder<DH> mDraweeHolder;
public void setController(@Nullable DraweeController draweeController) {
mDraweeHolder.setController(draweeController);
super.setImageDrawable(mDraweeHolder.getTopLevelDrawable());
}
所以方法又调用了DraweeHolder里面的setController()方法,对于DraweeHolder,个人感觉是起到了适配器的作用,也使得我们的代码更加易读吧。先不瞎扯看下DraweeHolder中的代码:
public void setController(@Nullable DraweeController draweeController) {
boolean wasAttached = mIsControllerAttached;
if (wasAttached) {
detachController();
}
//清除掉旧的Controller
if (isControllerValid()) {
//mEventTracker起到一个纪录的作用
mEventTracker.recordEvent(Event.ON_CLEAR_OLD_CONTROLLER);
mController.setHierarchy(null);
}
mController = draweeController;
if (mController != null) {
mEventTracker.recordEvent(Event.ON_SET_CONTROLLER);
mController.setHierarchy(mHierarchy);
} else {
mEventTracker.recordEvent(Event.ON_CLEAR_CONTROLLER);
}
if (wasAttached) {
//调用到该方法
attachController();
}
}
private void attachController() {
if (mIsControllerAttached) {
return;
}
mEventTracker.recordEvent(Event.ON_ATTACH_CONTROLLER);
mIsControllerAttached = true;
if (mController != null &&
mController.getHierarchy() != null) {
//调用Controller的onAttach()方法
mController.onAttach();
}
}
接下来就是看Controller的onAttach方法,在SimpleDraweeView中设置的PipelineDraweeController实例,onAttach方法定义于它的父类AbstractDraweeController中:
@Override
public void onAttach() {
if (FLog.isLoggable(FLog.VERBOSE)) {
FLog.v(
TAG,
"controller %x %s: onAttach: %s",
System.identityHashCode(this),
mId,
mIsRequestSubmitted ? "request already submitted" : "request needs submit");
}
mEventTracker.recordEvent(Event.ON_ATTACH_CONTROLLER);
Preconditions.checkNotNull(mSettableDraweeHierarc

本文深入解析了Android Fresco框架中ImagePipeline的调用过程,从SimpleDraweeView的setImageURI()方法开始,详细阐述了请求如何传递给ImagePipeline,以及如何直接操作ImagePipeline进行图片请求。同时介绍了DataSource、DataSubscriber的概念以及它们在异步操作中的作用。此外,还概述了ImagePipeline的关键方法,如fetchDecodedImage、prefetchToBitmapCache等,并展示了如何自定义ImageRequest并使用ImagePipeline进行图像请求。
最低0.47元/天 解锁文章
2606

被折叠的 条评论
为什么被折叠?



