Fresco 源码分析(四) 后台数据返回到前台的处理
来源:互联网 发布:淘宝差评不显示怎么办 编辑:程序博客网 时间:2024/06/10 04:05
AbstractDraweeController.submitRequest()源码分析 续
这部分的逻辑之前已经分析了一部分,在此我们分析一下关于回调处理的部分
……
1. 获取到数据源
2. 注册数据源的观察者(这里使用的回调是mUiThreadImmediateExecutor–>ui的线程池,关于这个线程池标记为Q8,这个是很好的一个封装,将UI线程封装为了线程池)
3. 对于返回的数据结果的处理体现在接口中DataSubscriber
protected void submitRequest() { mEventTracker.recordEvent(Event.ON_DATASOURCE_SUBMIT); getControllerListener().onSubmit(mId, mCallerContext); mSettableDraweeHierarchy.setProgress(0, true); mIsRequestSubmitted = true; mHasFetchFailed = false; mDataSource = getDataSource(); if (FLog.isLoggable(FLog.VERBOSE)) { FLog.v( TAG, "controller %x %s: submitRequest: dataSource: %x", System.identityHashCode(this), mId, System.identityHashCode(mDataSource)); } final String id = mId; final boolean wasImmediate = mDataSource.hasResult(); final DataSubscriber<T> dataSubscriber = new BaseDataSubscriber<T>() { @Override public void onNewResultImpl(DataSource<T> dataSource) { // isFinished must be obtained before image, otherwise we might set intermediate result // as final image. boolean isFinished = dataSource.isFinished(); float progress = dataSource.getProgress(); T image = dataSource.getResult(); if (image != null) { onNewResultInternal(id, dataSource, image, progress, isFinished, wasImmediate); } else if (isFinished) { onFailureInternal(id, dataSource, new NullPointerException(), /* isFinished */ true); } } @Override public void onFailureImpl(DataSource<T> dataSource) { onFailureInternal(id, dataSource, dataSource.getFailureCause(), /* isFinished */ true); } @Override public void onProgressUpdate(DataSource<T> dataSource) { boolean isFinished = dataSource.isFinished(); float progress = dataSource.getProgress(); onProgressUpdateInternal(id, dataSource, progress, isFinished); } }; mDataSource.subscribe(dataSubscriber, mUiThreadImmediateExecutor); }
再看回调的相关方法之前,先看看BaseDataSubscriber的相关类的继承体系
这个的设计方式与Consumer的设计模式类似,都是先是一个接口,然后抽象的一个实现Abstract***类中实现这些接口,然后暴露出相关的实现方法impl,这种设计的方式有很多好处,很值得我们借鉴,实现了面向接口的编程,同时,通用的逻辑又在抽象类中得以实现,接口相关的内容供外界调用,Impl的相关方法供内部实现.
BaseDataSubscriber类的源码
@Override public void onNewResult(DataSource<T> dataSource) { try { onNewResultImpl(dataSource); } finally { if (dataSource.isFinished()) { dataSource.close(); } } } @Override public void onFailure(DataSource<T> dataSource) { try { onFailureImpl(dataSource); } finally { dataSource.close(); } } @Override public void onCancellation(DataSource<T> dataSource) { } @Override public void onProgressUpdate(DataSource<T> dataSource) { } protected abstract void onNewResultImpl(DataSource<T> dataSource); protected abstract void onFailureImpl(DataSource<T> dataSource);
回到我们的正题,查看AbstractDraweeController的匿名BaseDataSubscriber实现类
* 匿名BaseDataSubscriber实现类相关源码*
还是以处理成功为例,这里会调用AbstractDraweeController的onNewResultInternal方法
new BaseDataSubscriber<T>() { @Override public void onNewResultImpl(DataSource<T> dataSource) { // isFinished must be obtained before image, otherwise we might set intermediate result // as final image. boolean isFinished = dataSource.isFinished(); float progress = dataSource.getProgress(); T image = dataSource.getResult(); if (image != null) { onNewResultInternal(id, dataSource, image, progress, isFinished, wasImmediate); } else if (isFinished) { onFailureInternal(id, dataSource, new NullPointerException(), /* isFinished */ true); } } @Override public void onFailureImpl(DataSource<T> dataSource) { onFailureInternal(id, dataSource, dataSource.getFailureCause(), /* isFinished */ true); } @Override public void onProgressUpdate(DataSource<T> dataSource) { boolean isFinished = dataSource.isFinished(); float progress = dataSource.getProgress(); onProgressUpdateInternal(id, dataSource, progress, isFinished); }
AbstractDraweeController.onNewResultInternal() 源码分析
逻辑如下:
1. 检查是否是自己想要的结果,如果不是,直接释放资源(感觉这块像是在fix bug 一样,没有注意到这块为何会如此处理,查看代码说是因为后续还是会返回之前的一些结果,所以这里做了这样的判断)
2. 根据返回的image信息,生成drawable
3. 如果是已经请求完成的信息,便直接将mDataSource设置为null(个人有点疑惑,命名在release的时候,会释放dataSource的信息,这里却直接设置为空,可能是为了第一步的资源检查或者说单纯的释放引用,让内存及时回收,如果有理解的请留言回复我,感谢)
4. 将drawable对象交给hierarchy来处理
5. 释放drawable的相关信息(这里指的是缓存之类的信息,为了节省内存空间,而没有释放drawble)
private void onNewResultInternal( String id, DataSource<T> dataSource, @Nullable T image, float progress, boolean isFinished, boolean wasImmediate) { // ignore late callbacks (data source that returned the new result is not the one we expected) if (!isExpectedDataSource(id, dataSource)) { logMessageAndImage("ignore_old_datasource @ onNewResult", image); releaseImage(image); dataSource.close(); return; } mEventTracker.recordEvent( isFinished ? Event.ON_DATASOURCE_RESULT : Event.ON_DATASOURCE_RESULT_INT); // create drawable Drawable drawable; try { drawable = createDrawable(image); } catch (Exception exception) { logMessageAndImage("drawable_failed @ onNewResult", image); releaseImage(image); onFailureInternal(id, dataSource, exception, isFinished); return; } T previousImage = mFetchedImage; Drawable previousDrawable = mDrawable; mFetchedImage = image; mDrawable = drawable; try { // set the new image if (isFinished) { logMessageAndImage("set_final_result @ onNewResult", image); mDataSource = null; mSettableDraweeHierarchy.setImage(drawable, 1f, wasImmediate); getControllerListener().onFinalImageSet(id, getImageInfo(image), getAnimatable()); // IMPORTANT: do not execute any instance-specific code after this point } else { logMessageAndImage("set_intermediate_result @ onNewResult", image); mSettableDraweeHierarchy.setImage(drawable, progress, wasImmediate); getControllerListener().onIntermediateImageSet(id, getImageInfo(image)); // IMPORTANT: do not execute any instance-specific code after this point } } finally { if (previousDrawable != null && previousDrawable != drawable) { releaseDrawable(previousDrawable); } if (previousImage != null && previousImage != image) { logMessageAndImage("release_previous_result @ onNewResult", previousImage); releaseImage(previousImage); } } }
在这里我们最关心的就是drawable交给hierarchy后是如何处理的
那就继续跟踪,
GenericDraweeHierarchy.setImage()
@Override public void setImage(Drawable drawable, float progress, boolean immediate) { drawable = maybeApplyRoundingBitmapOnly(mRoundingParams, mResources, drawable); drawable.mutate(); mActualImageSettableDrawable.setDrawable(drawable); mFadeDrawable.beginBatchMode(); fadeOutBranches(); fadeInLayer(mActualImageIndex); setProgress(progress); if (immediate) { mFadeDrawable.finishTransitionImmediately(); } mFadeDrawable.endBatchMode(); }
其实在这里面完成了图像的展示,但是单纯的如此查看这段逻辑,我们还是会感觉到有点迷惑,只是发现了drawable的一些变化,然后就没有了,那么处理的逻辑在哪里呢?其实这个是drawable的强大之处(为什么强大,大家可以先看看google android的官方网站上关于drawable的介绍以及再看看鸿洋大神关于drawable的一些案例介绍http://blog.csdn.net/lmj623565791/article/details/43752383),fresco自己又实现了一套drawable的继承体系,专门来处理ui上的一些变化效果,,接下来我也会提及一部分这方面的知识,便于大家理解.drawable的部分插叙完成后,我们继续分析Hierachy的相关知识
下篇链接:Fresco 源码分析(四) 后台数据返回到前台的处理 - Drawable体系的介绍(1)(http://blog.csdn.net/IEYUDEYINJI/article/details/48879647)
安卓源码分析群: Android源码分析QQ1群号:164812238
- Fresco 源码分析(四) 后台数据返回到前台的处理 - Drawable体系的介绍(1)
- Fresco 源码分析(四) 后台数据返回到前台的处理 - Drawable体系的介绍(2)
- Fresco 源码分析(四) 后台数据返回到前台的处理
- Fresco 源码分析(四) 后台数据返回到前台的处理 - Drawable体系的介绍(3) 遗留任务预览
- Fresco 源码分析(三) Fresco服务端处理(3) DataSource到Producer的适配器逻辑以及BitmapMemoryCacheProducer处理的逻辑
- ajax前台中文数据到后台处理接收时乱码
- Spring MVC处理前台到后台绑定时间格式、doble等数据的解决方式
- JSP_strut2架构下前台接收后台传递到前台之数据并处理以使用的一种方法
- ajax json 前台传数据到后台,后台接收并返回json 数据
- Fresco 源码分析(三) Fresco服务端处理(4) Producer处理体系的总结
- 前台遍历后台返回的json数据问题
- java中后台返回前台数据中文乱码的问题
- easy ui怎么把前台显示的dataGird中的所有数据序列化为json,返回到后台并解析
- Fresco 源码分析(三) Fresco服务端处理(2) Producer具体实现的内容
- Fresco 源码分析(三) Fresco服务端处理(2) Producer具体实现的内容
- 【easyui】 jq 表单返回的数据,动态增加部分数据后,提交到后台进行处理
- 利用Struts2框架,将后台数据转化为JSON数据并返回到前台
- java 后台返回json数据给前台
- Windows上wget的安装版本
- 使标签居中的方法
- Air中File类获取地址的研究
- Ecplise自动化测试覆盖率
- 选出每个班级总分前三的记录
- Fresco 源码分析(四) 后台数据返回到前台的处理
- Longest Valid Parentheses
- Android创建自定义键盘
- 编码与解码
- noip2005 谁拿了最多奖学金 (模拟)
- Java获取键盘输入的三种方法
- 学习矢量量化(LVQ)
- iOS项目开发实战——获取系统当前时间
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制