您的位置:首页 >  新闻中心 > 行业动态
  行业动态
 

Android搭建属于自己的技术堆栈和App架构

来源:原创    时间:2017-10-17    浏览:0 次

一、目录
 
前语 
APP的全体架构
技能选型的考量点
日志记载才能
JSON解析才能
数据库操作才能
网络通讯才能
图片缓存和显现才能
 
二、前语
 
在技能面试的时分必定都会问到运用了哪些第三方结构,为什么运用它而不必其他的。身边朋友就有这样的亲身经历:
 
面试官:你们项目中加载图片都是用的什么结构?
面试者:Glide啊(心里窃喜)
面试官:为什么运用Glide而不必其他的?
面试者:(缄默沉静10s),Glide好啊,我比较喜爱。(心里不安)
面试官:......(能不能好好谈天了)
 
这篇博文首要就是针对往常运用到的结构做一个收拾和剖析其好坏。
 
为了从全体上进行掌握,先来看看一个完好的APP全体架构
 
三、APP的全体架构
 
从较高的层次将,一个APP的全体架构能够分为两层,即运用层和根底结构层。
 
运用层专心于职业范畴的完结,例如金融、付出、地图导航、交际等,它直接面向用户,是用户对产品的第一层感知。
 
根底结构层专心于技能范畴的完结,供给APP公有的特性,防止重复制作轮子,它是用户对产品的第二层感知,例如功用、稳定性等。
 
一个抱负的APP架构,应该具有如下特色
 
支撑跨渠道开发
 
具有明晰的层次区分,同一层模块间充分化耦,模块内部契合面向目标规划六大准则
 
在功用、功用、稳定性等方面到达归纳最优
 
依据以上规划准则,我们能够看出APP架构图,最上层是运用层,运用层以下都归于根底结构层,根底结构层包含:组件层、根底层和跨渠道层。
 
我们要评论的重点是根底层,下面开端一步一步地论述怎么依据开源函数库建立归于自己的一个根底技能仓库。
 
四、技能选型的考量点
 
首先要清晰的是,我们挑选开源函数库或许第三方SDK、一般需求归纳考虑一下几个方面
 
特性:供给的特性是否满意项目的需求
 
可用性,是否供给了简练便当的API,便利开发者集成运用。
 
功用:功用不能太差,不然项目后边功用优化会过不去,可能回呈现需求替换函数库的状况。
 
文档:文档应该比较完全,且可读性高。
 
技能支撑:遇到问题或许发现BUG,是否能够及时得到官方的技能支撑是很重要的
 
巨细:引进函数库会添加APK的巨细,需求稳重挑选
 
办法数:如果函数库办法数太多,堆集起来会导致你的APP遇到64K问题,应该尽量防止
 
五、日志记载才能
 
日志记载不管在效劳端开发仍是移动端开发,都是一个根底且重要的才能,开发人员在代码调试以及过错定位进程中,大多说都要依靠日志信息,一个简练灵敏的日志记载模块是适当重要的。
 
Logger(https://github.com/orhanobut/logger) 是依据体系Log类根底上进行的封装,但新增了如下超赞的特性。
 
在Logcat中完美的格局化输出,再也不必忧虑和手机其他APP或许体系的日志信息相混杂了
 
包含线程、类、办法信息,能够清楚地看到日志记载的调用仓库
 
支撑跳转到源码处
 
支撑格局化输出JSON、XML格局信息
 
Logcat截图
 
当然Logger也不是齐备的,它尽管支撑格局化输出JSON、XML,但并不支撑比如List、Set、Map和数组等常见Java调集类的格局化输出。怎么处理呢?能够看下LogUtils (https://github.com/pengwei1024/LogUtils)这个开源库,它完结了Logger缺失的上述特性。
 
再者,Logger只支撑输出日志到Logcat,但项目开发中往往还存在将日志保存到磁盘上的需求,怎么将两者结合起来呢?这是可用timber(https://github.com/JakeWharton/timber) 。
 
timber是JakeWharton开源的一个日志记载库,它的特色是可扩展的结构,开发者能够便利快捷的集成不同类型的日志记载方法,例如,打印日志到Logcat、打印日志到文件、打印日志到网络等,timber经过一行代码就能够一起调用多种方法。
 
timber的思维很简略,就是保护一个森林目标,它由不同类型的日志树组合而成,例如,Logcat记载树、文件记载树、网络记载树等,森林目标供给对外的接口进行日志打印。每种类型的树都能够经过栽培操作把自己添加到森林目标中,或许经过移除操作从森林目标中删去,然后完结该类型日志记载的敞开和封闭。
 
终究我们的日志记载模块将由timber+Logger+LogUtils组成,当然轮子找到了,轮子的兼容兼并就得靠我们自己完结了,一起我们还得添加打印到文件的日志树和打印到网络的日志树完结。
 
六、JSON解析才能
 
移动互联网产品与效劳器端通讯的数据格局,如果没有特别需求的话,一般都运用JSON格局。Android体系也原生的供给了JSON解析的API,可是它的速度十分慢,并且没有供给简练便利的接口来进步开发者的功率和下降犯错的可能。所以我们就开端找第三方开源库来完结JSON解析,比较优异的包含如下几种。
 
gson
gosn是Google出品的JSON解析函数库,能够将JSON字符串反序列化对应的Java目标,或许反过来将Java目标序列化为对应的JSON字符串,免去了开发者手动经过JSONObject和JSONArray将JSON字段逐一进行解析的烦恼,也削减了犯错的可能性,增强了代码的质量。运用gson解析时,对应的Java实体类无需运用注解进行符号,支撑恣意杂乱Java目标包含没有源代码的目标。
 
jackson
jcakson是Java言语的一个盛行的JSON函数库,在Android开发中运用时,首要包含三部分。
 
jackson-core:JSON流处理中心库
 
jackson-databind:数据绑定函数库,完结Java目标和JSON字符串流的彼此改换。
 
jackson-annotations:databind运用的注解函数库
 
由于jackson是针对Java言语通用的JSON函数库,并没有为Android优化定制过,因而函数珍重包含许多非必要的API,比较其他的JSON函数库,用于Android渠道会更明显的增大终究生成的APK的体积。
 
Fastjson
Fastjson是阿里巴巴出品的一个Java言语编写的高功用且功用完善的JSON函数库。它选用一种“假定有序快速匹配”的算法,把JSON Parse的功用提升到极致,号称是现在Java言语中最快的JSON库。Fastjson接口简略易用,现已被广泛运用在缓存序列化、协议交互、Web输出、Android客户端等多种运用场景。
 
由于是Java言语通用的,因而,曾经在Android上运用时,Fastjson不行防止的引进了许多关于Android而言冗余的功用,然后添加了包巨细,许多人运用的就是标准版的fastjson,但事实上,fastjson还存在一个专门为Android定制的版别---fastjson.android 。和标准版别比较,Android版别去掉了一些Android虚拟机dalvik不支撑的功用,使得jar更小。
 
LoganSquare
LoganSquare是近两年兴起的快速解析和序列化JSON的Android函数库,其底层依据jackson的streaming API,运用APT(Android Annotation Tool)完结编译时注解,然后进步JSON解析和序列化的功用。官网上能够看到LoganSquare和gson、jackson databind的功用比照。
 
从功用方面看,LoganSquare是完胜gson和jackson的。如果和fastjson比较较,两者应该是平起平坐的。
 
再来看下jar包的巨细
 
gson:232KB
jackson:259+47+1229 = 1.5M
Fastjson:417KB
Fastjson.android:256KB
LoganSquare:48+259 = 307KB
 
从功用和包巨细归纳考虑,终究我们会挑选Fastjson.android作为根底技能仓库中的JSON解析和序列化库。
 
七、数据库操作才能
 
不管是iOS仍是Android,底层数据库都是依据开源的SQLite完结,然后在体系层封装成用于运用层的API。尽管直接运用体系的数据库API功用很高,可是这些API接口并不是很便利开发者运用,一不小心就会引进Bug,并且代码的视觉效果也欠安。为了处理这个问题,目标联系映射(ORM)结构呈现了,比较好的有ActiveAndroid,ormlite和greenDAO。
 
ActiveAndroid
ActiveAndroid是一种Active Record风格的ORM结构,Active Record(活动目录)是Yii,Rails等结构中对ORM完结的典型命名方法。它极大的简化数据库的运用,运用面向目标的方法办理数据库,离别手写SQL的前史。每一个数据库表都能够被映射为一个类,开发者只需运用类似save()或许delete()这样的函数即可。
 
不过ActiveAndroid现已基本上处于保护阶段了,最新的一个Release版别是在2012年发布的。
 
ormlite
ormlite是Java渠道的一个ORM结构,支撑JDBC衔接、Spring和Android渠道。在Android中运用时,它包含两部分。
 
ormlite-core:中心模块,不管在哪个渠道运用,都必须依据这个中心库,是完结ORM映射的要害模块。
 
ormlite-android:依据ormlite-core封装的针对Android渠道的适配器模块,Android开发中首要跟这个模块打交道。
 
与ActiveAndroid类似,ormlite也现已不是一个活泼的开源库,最近一次Release版别是在2013年发布的。
 
greenDAO
greenDAO是一个轻量级且快速的ORM结构,专门为Android高度优化和定制,它能够支撑每秒数千条记载的CRUD操作。官网上给出一张功用比照图
 
纵轴表明每秒履行的操作数。并且greenDAO处在高度活泼中,最新Release版别是在2017年3月份发布的。
 
Realm
Realm是一个全新的移动数据库引擎,它既不是依据iOS渠道的Core Data,也不是依据SQLite,它具有自己的数据库存储引擎,并完结了高效快速的数据库构建操作,比较Core Data和SQLite,Realm操作要快许多,跟ORM结构比较就更不必说了。
 
Realm的优点如下:
 
跨渠道:Android和iOS现已是事实上的两大移动互联网操作体系,绝大多数运用都会支撑这两个渠道。运用Realm,Android和iOS开发者无需考虑内部数据的架构,调用Realm供给的API即可轻松完结数据的交流。
用法简略:比较Core Data和SQLite所需的入门常识,Realm能够极大下降开发者的学习本钱,快速完结数据库存储功用。
可视化操作:Realm为开发者供给了一个轻量级的数据库可视化操作东西,开发者能够轻松检查数据库中的内容,并完结简略地刺进和删去等操作。
 
我们看下上述四种数据库包巨细。
 
activeandroid:40KB
greendao:100KB
ormlite-android:57KB
realm-android:4.2M
 
能够看出,前三个仍是正常规模,但Realm的巨细一般项目可能无法承受。这是由于不同CPU架构渠道的 .so 文件添加了整个包的巨细,由于arm渠道的so在其他渠道上面能够以兼容形式运转的,尽管会丢失功用,可是能够极大地削减函数库占用的空间。因而,能够挑选只保存armeabi-v7a和x86两个渠道的 .so 文件,直接删去无用的 .so 文件,或许经过工程的build.gradle文件中添加 ndk abi 过滤,句子如下:
 
因而,归纳功用考虑,包巨细以及开源库的可持续发展等要素,我终究挑选greenDAO。
 
八、网络通讯才能
 
现在的APP简直都需求从效劳器获取数据,不行防止的需求具有网络通讯的才能,不然就是一个死界面。
 
android-async-http
Android最经典的网络异步通讯函数库,它对Apache的HttpClient API的封装使得开发者能够简练高雅地完结网络恳求和呼应,并且一起支撑同步和异步恳求。首要特性如下:
 
支撑异步HTTP恳求,并在匿名回调函数中处理呼应
 
在子线程中建议HTTP恳求
 
内部选用线程池来处理并发恳求
 
经过RequestParams类完结GET/POST参数结构
 
无需第三方库支撑即可完结Multipart文件上传
 
库的巨细只要60KB
 
支撑多种移动网络环境下主动智能的恳求重试机制
 
HTTP呼应中完结主动的gzip解码,完结快速恳求呼应
 
内置多种形式的呼应解析,有原生的字节省、String、JSON目标,乃至能够将response写入到文件中。
 
可选的永久cookie保存,内部完结运用的是Android的SharedPreferences。
 
可是在6.0之后,体系对开发者躲藏了HttpClient函数库,这明显增大了运用android-async-http的价值。 如果铁了心想持续运用HttpClient,官方引荐的做法是在编译期引进org.apache.http.legacy 这个库,库目录在Android SDK目录下的platformsndroid-23optional中找到,它的作用是保证在编译时不会呈现找不到HttpClient相关API的过错,在运用运转时能够不依靠这个库,由于6.0以上的Android体系还没有真实移除HttpClient的代码,只不过API设置为对开发者不行见。我们检查android-async-http源码发现,需求运用下面这个函数库来替换之前的Apache的HttpClient。
 
这样明显的添加了APP的包的巨细,如果想持续运用android-async-http,那么你的APP需求额定添加1.1MB左右的巨细。
 
OkHttp
OkHttp是一个高效的HTTP客户端,具有如下特性。
 
支撑HTTP/2和SPDY,对同一台主机的一切恳求同享同一个socket。
 
当SPDY不行用时,运用衔接池削减恳求的推迟。
 
通明的GZIP紧缩削减下载数据巨细
 
缓存呼应防止重复的网络恳求
 
OkHttp在网络功用很差的状况下能够很好地作业,它能够防止常见的网络衔接问题。如果你的HTTP效劳有多个IP地址,OkHttp在第一次衔接失利是,会测验其他可选的地址。这关于IPv4+IPv6以及保管在冗余数据中心的效劳来说是必要的。OkHttp运用现代的TLS特性(SNI,ALPN)初始化HTTP衔接,当握手失利时,会下降运用TSL1.0初始化衔接。
 
OkHttp依靠于okio,okio作为java.io和java.nio的弥补,是square公司开发的一个函数库。okio使得开发者能够更好地拜访、存储和处理数据。一开端是作为OkHttp的一个组件存在的,当然我们也能够独自运用它。
 
运用Okhttp需求引进Jar包,包的巨细为:
326+66 = 392KB
 
Volley
Volley是Google在2013年发布的用于Android渠道的网络通讯库,能使网络通讯更快、更简略、更强健。Volley特别运用于数据量小等通讯频频的场景。
 
Volley是为了简化网络使命而规划的,用于协助开发者处理恳求、加载、缓存、多线程、同步等使命。Volley规划了一个灵敏的网络栈适配器,在Android2.2及之前的版别中,Volley底层运用Apache HttpClient,在Android2.3及以上版别中,它运用HttpURLConnection来建议网络恳求,并且开发者也很简略将网络栈切换成运用OkHttp。
 
Retrofit
确切的说,Retrofit并不是一个完好的网络恳求函数库,而是将REST API改换成Java接口的一个开源函数库,它要求效劳器API接口遵从REST标准。依据注解使得代码变得很简练,Retrofit默许状况下运用GSON作为JSON解析器,运用OkHttp完结网络恳求,三者一般合作运用,当然我们也能够将这两者换成其他的函数库。
 
经过以上剖析,HttpURLConnection、Apache HttpClient 和OkHttp封装了底层的网络恳求,而android-async-http,Volley和Retrofit是依据前面三者的根底上二次开发而成。
 
最终看下函数库的巨细
 
android-async-http:106KB+1.1MB = 1.2MB
OkHttp:326KB+66KB = 392KB
Volley:94KB
Retrofit:122KB+211KB = 333KB
九、网络通讯才能
 
图片缓存函数库有许多十分优异的,开发人员能够依据需求进行挑选。传统的图片缓存方案中设置有两级缓存,分别是内存缓存和磁盘缓存。在Facebook推出的Fresco中,它添加了一级缓存,也就是Native缓存,这极大地下降了运用Fresco的APP呈现OOM的概率。
 
BitmapFun
BitmapFun函数库是Android官方教程中的一个图片加载和缓存实例,关于简略的图片加载需求来说,运用BitmapFun就够了,在前期用的多,现在逐渐退出了实践项目开发的舞台。
 
Picasso
Picasso是闻名的square公司很多开源项目中的一个,它除了完结图片的下载和二级缓存功用,还处理了常见的一些问题。
 
在adapter中正常的处理ImageView收回和下载的撤销
 
运用尽量小的内存完结杂乱的图画改换
 
Glide
Glide是Google引荐的用于Android渠道上的图片加载和缓存函数库。这个库被广泛运用在Google的开源项目中,Glide和Picasso有90%的类似度,只是在细节上仍是存在不少差异。Glide为包含图片的翻滚列表做了尽可能流通的优化。除了静态图片,Glide也支撑GIF格局图片的显现。Glide供给了灵敏的API能够让开发者便利地替换下载图片所用的网络函数库,默许状况下,它运用HttpUrlConnection作为网络恳求模块,开发者也能够依据自己项目的实践需求灵敏运用Google的Volley或许Square的OkHttp等函数库进行替换。
 
Fresco
Fresco是Facebook开源的功用强大的图片加载和缓存函数库,比较其他图片缓存库,Fresco最明显的特色是具有三级缓存:两级内存缓存和一级磁盘缓存。首要特性如下:
 
渐进式地加载JPEG图片
 
显现GIF和WebP动画
 
可扩展,可自定义图片加载和显现
 
在Android 4.X和一下的体系上,将图片放在Android内存一个特别的区域,然后使得运用运转更流通,一起极大减低呈现OutOfMemoryError的过错。
 
Android-Universal-Image-Loader
Android-Universal-Image-Loader简称UIL,是Android渠道老牌的图片下载和缓存函数库,功用强大灵敏且高度可自定义,它供给一系列装备选项,并能很好地操控图片加载和缓存的进程。运用者甚多,现在项目仍在运用。UIL也支撑二级缓存,特性如下:
同步或异步的多线程图片加载
 
高度可自定义:线程池、下载器、解码器、内存和磁盘缓存、图片显现选项等。
 
每张图片的显现支撑多种自定义选项:默许存根图片、解码选项、Bitmap处理和显现等。
 
图片可缓存在内存或许磁盘(设备的文件体系或许SD卡)上。
 
可实时监听图片加载流程,包含下载进展。
 
最终看下几个库的包巨细
BitmapFun:71KB
Picasso:120KB
Glide:475KB
Fresco:47KB+93KB+93KB+10KB+3MB+62KB+8KB+111KB = 3.4MB
Android-Universal-Image-Loader:162KB
 
图片函数库的挑选需求依据APP的具体状况而定,关于严峻依靠图片缓存的APP,例如壁纸类,图片交际类APP来说,能够挑选最专业的Fresco。关于一般的APP,挑选Fresco会显得比较重,究竟Fresco 3.4MB的体量摆在这。
 
依据APP对图片显现和缓存的需求从低到高我们能够对以上函数库做一个排序
BitmapFun < Picasso < Android-Universal-Image-Loader < Glide < Fresco
 
值得一提的是,如果你的APP方案运用React Native进行部分模块功用的开发的话,那么在根底函数库挑选方面需求考虑和React Native的依靠库的复用,这样能够削减引进React Native 所添加的APP的巨细,能够复用的函数库有:OkHttp,Fresco,jackson-core.