java 图像对比 开源-如何基于开源函数库搭建属于自己的基础技术堆栈?
新媒体管家
点击上方“程序员共读”,选择“置顶公众号”
关键时刻,第一时间送达!
在技术面试的时候肯定都会问到使用了哪些第三方框架,为什么使用它而不用其他的。身边朋友就有这样的亲身经历:
面试官:你们项目中加载图片都是用的什么框架?
面试者:Glide啊(内心窃喜)
面试官:为什么使用Glide而不用其他的?
面试者:(沉默10s),Glide好啊,我比较喜欢。(内心不安)
面试官:……(能不能好好聊天了)
这篇博文主要就是针对平常使用到的框架做一个整理和分析其优劣。
为了从整体上进行把握,先来看看一个完整的APP整体架构
1. APP的整体架构
从较高的层次将,一个APP的整体架构可以分为两层,即应用层和基础框架层。
一个理想的APP架构,应该拥有如下特点
基于以上设计原则,我们可以看出APP架构图,最上层是应用层,应用层以下都属于基础框架层,基础框架层包括:组件层、基础层和跨平台层。
我们要讨论的重点是基础层,下面开始一步一步地阐述如何基于开源函数库搭建属于自己的一个基础技术堆栈。
2. 技术选型的考量点
首先要明确的是,我们选择开源函数库或者第三方SDK、一般需要综合考虑一下几个方面
3. 日志记录能力
日志记录无论在服务端开发还是移动端开发,都是一个基础且重要的能力,开发人员在代码调试以及错误定位过程中,大多说都要依赖日志信息,一个简洁灵活的日志记录模块是相当重要的。
Logger是基于系统Log类基础上进行的封装,但新增了如下超赞的特性。
Logcat截图
当然Logger也不是完备的,它虽然支持格式化输出JSON、XML,但并不支持诸如List、Set、Map和数组等常见Java集合类的格式化输出。如何解决呢?可以看下LogUtils这个开源库,它实现了Logger缺失的上述特性。
再者,Logger只支持输出日志到Logcat,但项目开发中往往还存在将日志保存到磁盘上的需求,如何将两者结合起来呢?这是就遇到了timber。
timber是JakeWharton开源的一个日志记录库,它的特点是可扩展的框架,开发者可以方便快捷的集成不同类型的日志记录方式,例如,打印日志到Logcat、打印日志到文件、打印日志到网络等,timber通过一行代码就可以同时调用多种方式。
timber的思想很简单,就是维护一个森林对象,它由不同类型的日志树组合而成,例如,Logcat记录树、文件记录树、网络记录树等,森林对象提供对外的接口进行日志打印。每种类型的树都可以通过种植操作把自己添加到森林对象中,或者通过移除操作从森林对象中删除,从而实现该类型日志记录的开启和关闭。
最终我们的日志记录模块将由timber+Logger+LogUtils组成java 图像对比 开源,当然轮子找到了,轮子的兼容合并就得靠我们自己实现了,同时我们还得增加打印到文件的日志树和打印到网络的日志树实现。
4. JSON解析能力
移动互联网产品与服务器端通信的数据格式,如果没有特殊需求的话,一般都使用JSON格式。Android系统也原生的提供了JSON解析的API,但是它的速度非常慢,而且没有提供简洁方便的接口来提高开发者的效率和降低出错的可能。所以我们就开始找第三方开源库来实现JSON解析,比较优秀的包括如下几种。
4.1 gson
gosn是Google出品的JSON解析函数库,可以将JSON字符串反序列化对应的Java对象,或者反过来将Java对象序列化为对应的JSON字符串,免去了开发者手动通过JSONObject和JSONArray将JSON字段逐个进行解析的烦恼,也减少了出错的可能性,增强了代码的质量。使用gson解析时,对应的Java实体类无需使用注解进行标记,支持任意复杂Java对象包括没有源代码的对象。
4.2 jackson
jcakson是Java语言的一个流行的JSON函数库,在Android开发中使用时,主要包含三部分。
由于jackson是针对Java语言通用的JSON函数库,并没有为Android优化定制过,因此函数保重包含很多非必要的API,相比其他的JSON函数库,用于Android平台会更显著的增大最终生成的APK的体积。
4.3 Fastjson
Fastjson是阿里巴巴出品的一个Java语言编写的高性能且功能完善的JSON函数库。它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,号称是目前Java语言中最快的JSON库。Fastjson接口简单易用,已经被广泛使用在缓存序列化、协议交互、Web输出、Android客户端等多种应用场景。
由于是Java语言通用的,因此,以前在Android上使用时,Fastjson不可避免的引入了很多对于Android而言冗余的功能,从而增加了包大小,很多人使用的就是标准版的fastjson,但事实上,fastjson还存在一个专门为Android定制的版本—fastjson.android。和标准版本相比,Android版本去掉了一些Android虚拟机dalvik不支持的功能,使得jar更小。
4.4 LoganSquare
LoganSquare是近两年崛起的快速解析和序列化JSON的Android函数库,其底层基于jackson的streaming API,使用APT(Android Annotation Tool)实现编译时注解,从而提高JSON解析和序列化的性能。官网上可以看到LoganSquare和gson、jackson databind的性能对比。
从性能方面看,LoganSquare是完胜gson和jackson的。如果和fastjson相比较,两者应该是不相上下的。
再来看下jar包的大小
从性能和包大小综合考虑,最终我们会选择Fastjson.android作为基础技术堆栈中的JSON解析和序列化库。
5. 数据库操作能力
无论是iOS还是Android,底层数据库都是基于开源的SQLite实现,然后在系统层封装成用于应用层的API。虽然直接使用系统的数据库API性能很高,但是这些API接口并不是很方便开发者使用,一不小心就会引入Bug,而且代码的视觉效果也不佳。为了解决这个问题,对象关系映射(ORM)框架出现了java 图像对比 开源,比较好的有ActiveAndroid,ormlite和greenDAO。
5.1 ActiveAndroid
ActiveAndroid是一种Active Record风格的ORM框架,Active Record(活动目录)是Yii,Rails等框架中对ORM实现的典型命名方式。它极大的简化数据库的使用,使用面向对象的方式管理数据库,告别手写SQL的历史。每一个数据库表都可以被映射为一个类,开发者只需使用类似save()或者delete()这样的函数即可。
不过ActiveAndroid已经基本上处于维护阶段了,最新的一个Release版本是在2012年发布的。
5.2 ormlite
ormlite是Java平台的一个ORM框架,支持JDBC连接、Spring和Android平台。在Android中使用时,它包含两部分。
与ActiveAndroid类似,ormlite也已经不是一个活跃的开源库,最近一次Release版本是在2013年发布的。
5.3 greenDAO
greenDAO是一个轻量级且快速的ORM框架,专门为Android高度优化和定制,它能够支持每秒数千条记录的CRUD操作。官网上给出一张性能对比图
纵轴表示每秒执行的操作数。而且greenDAO处在高度活跃中,最新Release版本是在2017年3月份发布的
5.4 Realm
Realm是一个全新的移动数据库引擎,它既不是基于iOS平台的Core Data,也不是基于SQLite,它拥有自己的数据库存储引擎,并实现了高效快速的数据库构建操作,相比Core Data和SQLite,Realm操作要快很多,跟ORM框架相比就更不用说了。
Realm的好处如下:
我们看下上述四种数据库包大小。
可以看出,前三个还是正常范围,但Realm的大小一般项目可能无法接受。这是因为不同CPU架构平台的 .so 文件增加了整个包的大小,由于arm平台的so在其他平台上面能够以兼容模式运行的,虽然会损失性能,但是可以极大地减少函数库占用的空间。因此,可以选择只保留armeabi-v7a和x86两个平台的 .so 文件,直接删除无用的 .so 文件,或者通过工程的build.gradle文件中增加 ndk abi 过滤,语句如下:
android { ... defaultConfig { ... ndk { abiFilters "armeabi-v7a", "x86" } }}
因此,综合性能考虑,包大小以及开源库的可持续发展等因素,我们最终选择greenDAO。
6. 网络通信能力
现在的APP几乎都需要从服务器获取数据,不可避免的需要具备网络通信的能力,否则就是一个死界面。
6.1 android-async-http
Android最经典的网络异步通信函数库,它对Apache的HttpClient API的封装使得开发者可以简洁优雅地实现网络请求和响应,并且同时支持同步和异步请求。主要特性如下:
但是在6.0之后,系统对开发者隐藏了HttpClient函数库,这显著增大了使用android-async-http的代价。 如果铁了心想继续使用HttpClient,官方推荐的做法是在编译期引入org.apache.http.legacy这个库,库目录在Android SDK目录下的platformsandroid-23optional中找到,它的作用是确保在编译时不会出现找不到HttpClient相关API的错误,在应用运行时可以不依赖这个库,因为6.0以上的Android系统还没有真正移除HttpClient的代码,只不过API设置为对开发者不可见。我们查看android-async-http源码发现,需要使用下面这个函数库来替换之前的Apache的HttpClient。
dependencies { compile 'cz.msebera.android:httpclient:4.3.6'}
这样显著的增加了APP的包的大小,如果想继续使用android-async-http,那么你的APP需要额外增加1.1MB左右的大小。