十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
对比现在主流图片框架的优势和缺点,在实际项目中如何选择适合自己的框架;
成都创新互联公司专注于企业全网整合营销推广、网站重做改版、醴陵网站定制设计、自适应品牌网站建设、H5技术、购物商城网站建设、集团公司官网建设、成都外贸网站建设公司、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为醴陵等各大城市提供网站开发制作服务。
Glide、Fresco、Picasso、ImageLoader
共同优点:
以上名词介绍
在分析他们的差异、优缺点之前,我们先了解图片缓存通用的概念:
以上概念在不同框架之间可能不同,比如Displayer在ImageLoader中叫做ImageAware,在Picasso和Glide中叫做Target。
以上为Glide的总体设计图。
整个库分为RequestManager(请求管理器)、Engine(数据获取引擎)、Fetcher(数据获取器)、MemoryCache(内存缓存)、DiskLRUCache(本地缓存)、Transformation(图片处理)、Encoder(编码处理)、Registry(图片类型以及解析器配置)、Target(目标)等模块。
简单流程: Glider收到加载及显示资源任务,创建Request并将它交给RequestManager,Request启动Engine去数据源获取资源,得到资源后通过Transformation处理后交给Target.
Glide依赖DiskLRUCache、GifDecoder等开源库去完成本地缓存和Gif图片解密工作;
为Bitmap 维护一个BitmapPool对象池, 对象池的主要目的是通过减少大对象的分配以重用来提高性能!
缺点 :
①图片质量低:因为机制不同,速度快,但是图片的质量降低了RGB565;
②多尺寸缓存导致内存和磁盘占用多:根据ImageView大小来缓存,可能会导致一张图片可能根据展示情况来缓存不同尺寸的几份;
扩展理解参考:
以上为Picasso的总体设计图。
整个库分为Dispatcher、RequestHandler以及Downloader、PicassoDrawable等模块。
简单流程: Picasso收到加载显示图片任务后,创建Request并将它交给Dispatcher,Dispatcher分发任务到具体RequestHandler,任务通过MemoryCache及Handler(数据获取接口)获取图片,图片获取成功后通过PicassoDrawable显示到Target中;
上面Data的File system部分,Picasso没有自定义本地缓存的接口,默认使用http的本地缓存,API19以上使用okhttp,一下使用UrlConnection,所以如果需要自定义本地缓存就需要自定义Downloader;
缺点 :加载速度没有其他框架快;
特点 :只缓存一个全尺寸的图片,根据需求的大小在压缩转换;
以上为Fresco的总体设计图
整个库分为UI:DraweeView(View控件)、Drawable(图片数据)、DraweeController(图片控制器)、DraweeHiierarchy(图片体系);Core:DataSource(数据源)、ImagePipeline(图像管道)、Producer(生产者)、ProducerFacotry(生产工厂)、Subcriber(订阅)、Supplier(供应者)、Consumer(消费者);IO/Data:MemoryCache(内存缓存)、Network、DiskCache(磁盘缓存)、Recourse(本地资源)
简单流程: 从上面的结构可以看出,fresco主要采用了工厂+建造者的模式实现功能,逻辑划分比较清楚;Fresco框架整体是一个MVC模式,DrawableView---View用来显示顶层视图、DrawableController---Control控制加载图片的配置 事件的分发、DrawableHierarchy---Model 用于存储和描述图片信息,同时也封装了一些图片的显示和视图层级的方法;ImagePipeline模块负责从网络、本地文件系统、本地资源加载图片
缺点:
①框架大,影响Apk体积;
②一定的学习成本,使用比较繁琐,需要使用内部提供的ImageView控件,使用起来比较复杂;
先上效果图
1.为了实现图片的放到缩小,我选择了 PhotoView 框架用于显示图片。
2.使用 Glide 框架加载图片
3.实现原理:
通过自定义View继承FrameLayout,以PhotoView作为背景,动态添加ImageView作为点。
4.主要分析:
1)标签随图片移动:通过实现PhotoView的OnMatrixChangedListener接口,监听图片的位置及大小,动态设置标签的位置
2)点击图片任意位置,在此位置生成标签,
3)标签添加后,会导致布局重新测量,此时会导致已经放大的图片回到初始的位置及大小,在onLayout方法中重新设置photoView的Matrix。
矩形框的实现原理类似,难点就是在给icon添加了移动监听,保证icon可随处移动
下面是源码地址
Android模块化设计方案系列文章:
1、 Android模块化设计方案模型图
2、 Android模块化设计方案之接口API化
3、 Android模块化设计方案之使用代理模式解耦
本篇是Android模块化设计方案的第三篇,也是对 第一篇 中ThridLibs Proxy模块进行说明。
很多人觉得对那些优秀的第三方依赖库再次封装是一件多余的事情,因为这些库可能出自大神/大厂,或有非常高的star并且使用起来十分稳定,可以在项目中直接拿来使用。当然每个开发者都有自己的态度,我也只是根据以往的经验,表达一下自己的看法。
作为从了解四大组件就不愁找不到工作的互联网大时代中一路走来的Android老鸟,经历了网路请求框架从HttpConnection到Volley再到OkHttp,也经历了图片加载框架从UniversalImageLoader到Picasso再到Gilde,技术的迭代随时都会发生。让项目架构具有良好的扩展性是在设计之初就需要考虑的东西。
那么接下来我用一个简单的demo来演示一下如何使用代理模式对第三方框架进行解耦。
现在我们有一个名为 thirdlib 的模块,为我们提供图片加载功能。
第一步:我们创建了一个新的模块 thridlibproxy ,并且该模块依赖于 thirdlib ,我们在该模块中创建包私有的接口ImageLoaderInterface,这个接口中把thirdlib模块中提供的功能抽象为接口:
第二步:创建包私有的接口的实现类ImageLoaderOneImpl,类中图片加载的业务逻辑是通过调用 thirdlib 中的ImageLoader类实现的:
第三步:我们提供一个供外部调用的ImageLoaderOneImpl接口代理类ImageLoaderProxy:
最后我们就可以通过ImageLoaderProxy中提供的loadImage方法进行图片的加载了。
看到这里有些盆友就会问了,在第二步的时候,我们就完成了 thirdlib 的封装工作,为什么还要有第三步?还有我写一个单例类直接对 thirdlib 进行封装不就行了,为什么还要抽象出接口?
原因很简单,为的就是尽可能的满足软件设计七大原则中的第一个: 开闭原则 。
一个好的软件设计,需要对拓展开放,对修改关闭。我们在设计之初就要想到,在更换图片加载框架之后如何最大程度上满足开闭原则。
如果直接对 thirdlib 进行封装,是面向类的开发而不是面向接口。如果此时更换图片加载类库,那必然会对封装出来的类进行大量的修改,把原来的实现替换为新的实现。
使用代理模式的好处就是,我新创建一个被代理的类ImageLoaderTwoImpl:
然后只需要对第三步中的被代理类进行替换就行了。
在想要达到相同效果的时候,最大程度的满足了开闭原则。
我们业务层模块也和第三方库实现了完全的解耦,我不需要知道 thridlibproxy 是如何帮我完成图片加载工作的,但是只要调用它提供的方法就完事儿的,这也符合软件设计七大原则中的: 最少知道原则 。
关于为何以及怎么通过代理调用第三方依赖库,到这里就介绍完毕了,赶快动手试试吧~
我只想说: 原则是死的,人是活的????
如果觉得有收获的话,欢迎点赞评论以及关注~
android应用开发框架是 Application Framework. 其系统架构由5部分组成,分别是:Linux Kernel、Android Runtime、Libraries、Application Framework、Applications。第二部分将详细介绍这5个部分。下面自底向上分析各层。
Android架构
1、Linux Kernel
Android基于Linux 2.6提供核心系统服务,例如:安全、内存管理、进程管理、网络堆栈、驱动模型。Linux Kernel也作为硬件和软件之间的抽象层,它隐藏具体硬件细节而为上层提供统一的服务。 如果你学过计算机网络知道OSI/RM,就会知道分层的好处就是使用下层提供的服务而为上层提供统一的服务,屏蔽本层及以下层的差异,当本层及以下层发生了变化不会影响到上层。也就是说各层各尽其职,各层提供固定的SAP(Service Access Point),专业点可以说是高内聚、低耦合。 如果你只是做应用开发,就不需要深入了解Linux Kernel层。
2、Android Runtime
Android包含一个核心库的集合,提供大部分在Java编程语言核心类库中可用的功能。每一个Android应用程序是Dalvik虚拟机中的实例,运行在他们自己的进程中。Dalvik虚拟机设计成,在一个设备可以高效地运行多个虚拟机。Dalvik虚拟机可执行文件格式是.dex,dex格式是专为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统。 大多数虚拟机包括JVM都是基于栈的,而Dalvik虚拟机则是基于寄存器的。两种架构各有优劣,一般而言,基于栈的机器需要更多指令,而基于寄存器的机器指令更大。dx 是一套工具,可以将 Java .class 转换成 .dex 格式。一个dex文件通常会有多个.class。由于dex有时必须进行最佳化,会使文件大小增加1-4倍,以ODEX结尾。 Dalvik虚拟机依赖于Linux 内核提供基本功能,如线程和底层内存管理。
3、Libraries
Android包含一个C/C++库的集合,供Android系统的各个组件使用。这些功能通过Android的应用程序框架(application framework)暴露给开发者。下面列出一些核心库: 系统C库--标准C系统库(libc)的BSD衍生,调整为基于嵌入式Linux设备 媒体库--基于PacketVideo的OpenCORE。这些库支持播放和录制许多流行的音频和视频格式,以及静态图像文件,包括MPEG4、 H.264、 MP3、 AAC、 AMR、JPG、 PNG 界面管理--管理访问显示子系统和无缝组合多个应用程序的二维和三维图形层 LibWebCore--新式的Web浏览器引擎,驱动Android 浏览器和内嵌的web视图 SGL--基本的2D图形引擎 3D库--基于OpenGL ES 1.0 APIs的实现。库使用硬件3D加速或包含高度优化的3D软件光栅 FreeType --位图和矢量字体渲染 SQLite --所有应用程序都可以使用的强大而轻量级的关系数据库引擎
4、Application Framework
通过提供开放的开发平台,Android使开发者能够编制极其丰富和新颖的应用程序。开发者可以自由地利用设备硬件优势、访问位置信息、运行后台服务、设置闹钟、向状态栏添加通知等等,很多很多。 开发者可以完全使用核心应用程序所使用的框架APIs。应用程序的体系结构旨在简化组件的重用 ,任何应用程序都能发布他的功能且任何其他应用程序可以使用这些功能(需要服从框架执行的安全限制)。这一机制允许用户替换组件。 所有的应用程序其实是一组服务和系统,包括: 视图(View)--丰富的、可扩展的视图集合,可用于构建一个应用程序。包括包括列表、网格、文本框、按钮,甚至是内嵌的网页浏览器 内容提供者(Content Providers)--使应用程序能访问其他应用程序(如通讯录)的数据,或共享自己的数据 资源管理器(Resource Manager)--提供访问非代码资源,如本地化字符串、图形和布局文件 通知管理器(Notification Manager)--使所有的应用程序能够在状态栏显示自定义警告 活动管理器(Activity Manager)--管理应用程序生命周期,提供通用的导航回退功能
5、Applications
Android装配一个核心应用程序集合,包括电子邮件客户端、SMS程序、日历、地图、浏览器、联系人和其他设置。所有应用程序都是用Java编程语言写的。更加丰富的应用程序有待我们去开发! 从上面我们知道Android的架构是分层的,非常清晰,分工很明确。Android本身是一套软件堆迭(Software Stack),或称为「软件迭层架构」,迭层主要分成三层:操作系统、中间件、应用程序。从上面我们也看到了开源的力量,一个个熟悉的开源软件在这里贡献了自己的一份力量。