|
链接:
本文由作者授权发布。
在技术面试中,面试官往往会询问应聘者使用了哪些第三方框架,以及为何选择该框架而非其他选项。我身边就有朋友曾有过这样的亲身经历:
面试官:你们项目中加载图片都是用的什么框架?
面试者:Glide啊(内心窃喜)
面试官:为什么使用Glide而不用其他的?
面试者:(沉默了10秒钟),Glide这款软件挺不错的,我个人挺喜欢的。(心中感到些许不安)
面试官:......(能不能好好聊天了)
本文的核心内容是对日常所用的框架进行归纳与评估,分析其优缺点。
为了从整体上进行把握,先来看看一个完整的APP整体架构
1. APP的整体架构
从宏观角度分析,一个应用程序的整体结构可以被划分为两个主要部分,分别是应用层面和底层框架层面。
一个理想的APP架构,应该拥有如下特点
依据上述设计理念,观察APP的架构图可知,其最顶层为应用层;而在应用层之下,则是构成基础框架层的各个部分,这些部分涵盖了组件层、基础层以及跨平台层。
我们的讨论焦点将集中在基础层,接下来,我们将逐步展开,详细介绍如何利用开源函数库构建我们独特的基础技术架构。
2. 技术选型的考量点
首先需明确,当我们挑选开源函数库或第三方SDK时,通常需要全面考虑以下数个要素。
3. 日志记录能力
日志记录在服务端和移动端开发中均扮演着基础且关键的角色,开发者在进行代码调试和错误追踪时,往往需要依赖日志信息,因此,构建一个简洁且灵活的日志记录系统显得尤为必要。
这是在系统Log类的基础上进行的封装,并且加入了以下非常出色的特性。
截图
当然,这并非一个全面的功能,尽管它能够实现JSON和XML格式的输出,但对于Java中常见的List、Set、Map以及数组等集合类型的格式化输出,则无法提供支持。
如何解决呢?可以看下 这个开源库,它实现了缺失的上述特性。
此外,虽然目前仅能将日志输出至特定位置,但在项目开发过程中,常常需要将日志信息保存至硬盘,那么如何实现这两种需求的融合呢?这便成为了我们面临的一大挑战。
这是一个开源的日志记录工具,其显著特点是具备可扩展的架构,使得开发者能够轻松高效地整合多样化的日志记录手段,诸如将日志输出至控制台、写入文件或发送至网络等,仅需一行代码即可实现多种记录方式的并行调用。
理念相当简洁,旨在构建一个森林对象,该对象由多种日志树构成,诸如记录树、文件记录树、网络记录树等。此森林对象对外开放接口,用于日志信息的打印。各类日志树均能通过种植动作加入森林对象,亦可通过移除动作从其中移除,以此达到对特定类型日志记录功能的开启与关闭。
我们的日志记录模块最终将由++构成,尽管我们已经找到了所需的轮子,但轮子的兼容与整合工作仍需我们自行完成。此外,我们还需增设两个功能,一个是将日志打印至文件,另一个则是将日志传输至网络。
4. JSON解析能力
移动互联网产品在服务器端进行数据交互时,通常采用JSON格式,除非有特定需求。系统内置了JSON解析的API,但该API运行速度较慢,且未提供便捷的接口以提升开发效率及减少错误发生率。因此,我们着手寻找第三方开源库以实现JSON解析功能,其中表现较为出色的库有以下几个。
4.1 gson
gosn是一款JSON解析库,它能够将JSON格式的字符串转换成相应的Java对象,亦或将Java对象转换成JSON格式的字符串。这样的功能大大减轻了开发者手动解析JSON字段的工作量,降低了出错的风险,从而提高了代码的整体质量。在应用gson进行解析的过程中,无需对相应的Java实体类添加任何注解来标识,该工具能够处理各种复杂的Java对象,即便这些对象没有源代码也能得到有效支持。
4.2
Java语言中广泛应用的JSON处理库,其应用过程中主要包括三个核心组成部分。
鉴于该函数库是专为Java语言设计的通用JSON处理库,并未针对性能进行特别优化,故其中包含了大量非核心的API。这与其他JSON库相比,在应用于平台时,会导致最终生成的APK文件体积明显增大。
4.3
这是由阿里巴巴公司开发的一款以Java语言为基础的高性能、功能全面的JSON处理库。该库运用了一种“预设有序快速匹配”的算法,将JSON解析的效率推至顶峰,被誉为Java语言中最快的JSON处理工具。其接口设计简洁直观,易于操作,已在缓存序列化、协议通信、Web输出、客户端等多个应用领域得到广泛应用。
Java语言本身具有通用性,故在使用过程中,难免会包含一些对于某些用户而言显得多余的功能。这些功能的存在,导致包的体积增大。尽管多数用户选择了标准版,但实际上,还存在着一个专为定制设计的版本——(版本)。相较于标准版,该版本剔除了虚拟机不支持的功能,从而使得生成的jar文件体积更小。
4.4
该函数库在近两年崭露头角,专注于快速解析与序列化JSON数据,其构建基础是API,并利用APT(注解工具)在编译阶段进行注解,以此提升JSON解析与序列化的效率。在官方网站上,您可以找到它与gson等工具的性能对比数据。
在性能表现上,它全面超越了gson和的同类产品。若与同类产品进行对比,两者的表现可以说是旗鼓相当。
再来看下jar包的大小
在全面考量性能和文件体积后,我们决定选取该库作为构建基础技术栈时处理JSON数据的解析与序列化工具。
5. 数据库操作能力
iOS系统以及类似系统,其底层数据库均采用开源版本进行构建,并在系统层面将其封装为适用于应用层的API。尽管系统数据库API在性能上表现优异,但这类API接口对于开发者来说并不十分便捷,使用不当容易导致Bug的产生,同时代码的可视化效果也并不理想。为此,对象关系映射(ORM)框架应运而生,其中表现较为出色的包括、等。
5.1
这是一种特定风格的对象关系映射(ORM)框架,在诸如Yii、Rails等框架中,对ORM的实现通常采用(活动目录)这种命名方法。它显著地简化了数据库的操作,通过面向对象的方法来管理数据库,使得不再需要手动编写SQL语句。每个数据库表都能对应一个类,开发者通过调用诸如save()或类似的函数就能轻松完成数据库操作。
该系统目前已基本进入维护期,而最新版本则是在2012年正式推出的。
5.2
这是一款运行在Java平台之上的对象关系映射(ORM)框架,它能够实现与JDBC连接及不同平台的兼容。在具体应用中,该框架由两个主要部分构成。
与那些类似的项目一样,它已不再是一个活跃的开源库项目,其最新的版本发布于2013年。
5.3
这是一款轻便且运行效率高的对象关系映射工具,特别适用于深度优化和个性化配置,并且具备每秒钟处理数千条数据记录的CRUD操作能力。
官网上给出一张性能对比图
纵轴展示了每秒钟所进行的操作数量。此外,它正处于极高的活跃状态,而其最新版本则是在2017年3月正式推出的。
5.4 Realm
Realm是一款创新的移动数据库驱动程序,与iOS系统的Core Data截然不同,它并非依托于其他平台,而是独立构建了自己的数据存储机制。该引擎在创建数据库方面表现出极高的效率与速度,相较于Core Data而言,其操作速度更为优越,更遑论与对象关系映射(ORM)框架相比。
Realm的好处如下:
我们看下上述四种数据库包大小。
观察下来,前三个参数仍在常规区间内,然而,Realm的尺寸对于一般项目来说往往难以接受。这主要是因为不同CPU架构平台的.so文件会扩大整个包的体积,尽管arm平台的so在其他平台上能够以兼容模式执行,尽管这样做会牺牲性能,但它能显著降低函数库所占用空间的大小。
因此,我们可以选择仅保留-v7a和x86两个平台的.so文件,直接移除不必要的.so文件,或者通过在工程的build文件中加入ndk abi筛选条件,具体操作语句如下:
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="" style=" -webkit-print-color-adjust: exact; background-color: rgb(245, 242, 240); border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); font-size: 13px; line-height: 1.5; overflow: auto; padding: 1em; border-radius: 3px; text-shadow: white 0px 1px; ; ; ; ; ; ; ; "><code class="" style=" -webkit-print-color-adjust: exact; border-width: initial; border-style: none; border-color: initial; border-radius: 3px; background-image: none; text-shadow: white 0px 1px; ; ; ; ; ; ; ; ; ; ">android {
...
defaultConfig {
...
ndk {
限制筛选条件为"armeabi-v7a"和"x86"。
}
}
}</code></pre></p>
因此,在全面评估性能、软件体积以及开源库的长期发展潜力等多方面因素后,我们决定采用。
6. 网络通信能力
绝大多数应用程序都必须依赖服务器来获取信息,这便使得它们必须拥有网络交互的功能,否则它们将仅仅是一个无法互动的静态界面。
6.1 -async-http
这是最为经典的网络异步通信函数库之一,其API的封装设计让开发者能够以简洁而优雅的方式完成网络请求与响应的处理,而且该库还具备了同时支持同步与异步请求的能力。其主要特点包括:
自6.0版本起,系统对开发者实施了函数库的隐蔽处理,此举无疑大幅提升了使用-async-http所带来的成本。若决心持续采用,官方建议在编译阶段引入名为org..http.的库,此库位于SDK目录下的\-23\子目录中。其功能在于防止编译过程中出现因API未找到而导致的错误。值得注意的是,在应用运行阶段,无需依赖此库,因为6.0及以上版本的系统虽未完全移除相关代码,但已将API设置为开发者不可见。
在查阅了-async-http的源码后,我们发现有必要用以下这个函数库来替代之前所用的库。
<p style='margin-bottom:15px;color:#555555;font-size:15px;line-height:200%;text-indent:2em;'> <pre class="" style=" -webkit-print-color-adjust: exact; background-color: rgb(245, 242, 240); border-width: 1px; border-style: solid; border-color: rgb(204, 204, 204); font-size: 13px; line-height: 1.5; overflow: auto; padding: 1em; border-radius: 3px; text-shadow: white 0px 1px; ; ; ; ; ; ; ; "><code class="" style=" -webkit-print-color-adjust: exact; border-width: initial; border-style: none; border-color: initial; border-radius: 3px; background-image: none; text-shadow: white 0px 1px; ; ; ; ; ; ; ; ; ; ">dependencies {
将 'cz.msebera.android:httpclient:4.3.6' 包编译入项目中。
}</code></pre></p>
这种做法显著扩大了APP安装包的体积,若用户希望继续使用该功能,那么他们的APP将不得不额外增加大约1.1MB的空间。 |
|