Android系统上移动组件化应用框架设计
2022-10-10李勇张俊
李 勇 张 俊
1(中科美络科技股份有限公司 安徽 合肥 230000) 2(中国科学院合肥物质科学研究院 安徽 合肥 230000)
0 引 言
移动互联网就是将移动通信和互联网相结合起来,其正逐渐渗透到我们的生活、学习和工作当中。随着移动互联网用户规模激增,移动应用市场成为企业发展的必争之地[2]。
随着Android版本6.0以后,Android Studio(AS)成为主流的开发工具,其集成开发环境(IDE)提供了丰富的功能插件和高效的用户体验。此时,单一工程开发框架随着用户需求的增长,其代码逐渐变得臃肿和高耦合,任何修改需编译整个项目工程,调试非常耗时,且影响团队协同开发效率。因此,接入组件化开发是未来Android大型工程开发的趋势[5]。
本文基于组件化和分层设计思想,同时结合多渠道深度定制的特点,提出了一种移动端组件化开发框架设计方案。本应用框架基于Android系统移动设备平台,实现一套代码管理生成多个App应用的需求[8]。特别是在项目庞大、功能模块复杂的场景下,其可以实现团队人员的并行研发及应用组件的单独编译运行,有助于提高研发效率。
1 组件化和相关技术介绍
1.1 组件化原理
Android组件化设计使用的IDE是Android Studio(AS)。AS不仅提供Android软件开发环境,而且IDE提供Gradle插件负责项目编译过程,组件化的实现就是由AS集成的Modules功能与编译插件Gradle完成[10]。AS项目中,可以添加library库作为一个独立的依赖文件,为主工程提供功能服务和数据服务[11]。而IDE提供的Gradle插件,负责Android工程的依赖、编译、打包等过程,组件化设计使用Gradle插件在通用构建规则下,通过Groovy语言为Gradle制定新的构建规则,动态改变项目的编译过程[11]。在开发阶段,通过修改Gradle文件配置,将组件变成可独立运行模式;在集成阶段,通过修改Gradle文件配置,将组件变成library依赖添加到App主体工程中。
1.2 组件化开发框架
组件化开发是把重复代码提炼封装成一个个组件提供功能服务,即把一个App拆分成多个Module,每个Module就是一个组件,各组件间低耦合、高内聚,可以相互调用,但不能相互依赖,每个组件可以单独调试运行,组合各组件就可以得到一个完整的应用[10]。
组件化开发能降低Android业务开发的耦合性、提高编译速度和协同开发效率,是未来Android大型工程开发的趋势[4]。通常组件的划分一般包括App壳工程、业务组件和功能组件(含第三方库),如图1所示,但随着需求的增多与版本的迭代升级,带来的主要问题就是框架层次不清晰,不利于后续维护。
图1 组件化开发框架结构图
知乎Android客户端早期使用的也是单一工程开发框,所有业务逻辑都放在主工程App中,后来随着业务的发展,代码耦合导致的问题逐渐显现出来,开始采用组件化重构,分为主工程、业务组件、基础组件、基础SDK[8],如图2所示。该开发框架是组件化开发框架实践的一个很好案例,但随着用户需求的变化,深度定制的问题就显现出来,特别是面向不同客户群体的私有化部署,对App名称、logo和启动页等都有差异化要求,需要满足做好一套代码管理生成多个App应用的需求,以提高开发效率,节约企业人力成本。
图2 知乎Android组件化开发框架结构图
1.3 多渠道打包
多渠道包是为了满足在不同应用市场运营统计的需求,在安装包中添加不同标识的过程[5]。基于IDE提供的Gradle插件来修改manifest中的mate-date内容,可以在Java中通过API获取对应的统计数据。
多渠道打包分为两种,第一种是为了简单的渠道标识,通常在代码中做一些必要的逻辑处理;第二种是为了对代码、资源、配置等做深度的定制,如设置不同的AppId、启动页、logo和App名称等,通常采用官方的productflavors实现[8]。本文采用第二种实现方式,以实现App的深度定制,满足市场的需要。
2 移动组件化应用框架设计
2.1 应用框架整体设计
本应用框架一共分为四层,从低到高依次是基础功能组件层、基础业务组件层、普通业务组件层、宿主层(App壳工程),其中基础功能组件层和基础业务组件层构成移动端基础中台。该框架能解决单一工程开发架构和组件层次不清的问题,具有以下优点:
(1) 解耦性:组件之间相互解耦,彼此互不影响,业务组件之间通过路由进行通信;(2) 可定制:通过多渠道配置,可以定制不同应用ID的App,批量生成多个不同应用App;(3) 层次性:对移动端基础中台再划分,使框架层次更加清晰,符合“组件化架构”的思想。
同时,各组件层之间须遵循两个原则:(1) 只有上层组件才能依赖下层组件,不能反向依赖;(2) 同层之间的组件不能相互依赖,以达到组件间解耦的目的。
图3为移动端组件化应用框架结构图。
图3 基于Android系统的组件化应用框架结构图
2.2 应用框架各层实现
2.2.1基础功能组件层
开发应用程序过程中,工具类是帮助我们快速开发的基础,它不但可以精简代码结构,还有利于提高团队开发效率。该层组件是对基础功能的抽取,封装成一些通用的工具类,不包含任何业务逻辑,为上层提供简洁、易用的访问接口[7]。例如:网络访问组件封装了网络的请求访问能力;数据存储组件封装了数据缓存的能力;版本更新组件封装了App应用版本升级的能力;自定义view组件提供了全局通用的视图资源库。
2.2.2基础业务组件层
除了基础工具类的封装,在系统开发过程中,一些通用的业务能力也可以封装成组件。它对下依赖基础功能组件,对上提供支撑上层业务组件运行的通用业务能力。例如公共业务组件,它封装了BaseActivity、BaseFragment、BaseApplication等基类信息;推送能力组件,它封装了极光、个推等消息推送能力;支付能力组件,它提供支付宝、微信和银联支付能力等。对基础业务组件进行封装,建立移动端基础业务中台,将移动端应用框架核心能力以共享服务中心进行沉淀,能最大限度地提升团队协作效率[6]。
2.2.3普通业务组件层
普通业务组件层是业务组件存放的容器,它包含业务组件和核心路由组件两个部分。每个业务组件既可以单独打包成APK在手机上运行,又可以向上提供给宿主层集成。同时每个业务组件通过核心路由组件实现业务通信,实现业务组件之间的解耦。
图4为移动端业务组件化通信结构图。
图4 业务组件通信结构图
(1) 业务组件。业务组件通常按照功能模块进行划分[10],如图5所示。例如用户模块组件封装了用户个人中心业务相关的功能模块,包括注册登录等;积分模块组件封装了积分业务相关的功能模块等。通过Gradle脚本配置方式,实现集成模式和组件模式切换,其中组件模式需要对AndroidManifest文件中设置入口Activity,即可单独运行编译,以提高开发人员调试编译效率;集成模式则以library形式集成在宿主层。其配置是在业务组件的build.gradle中,关键配置如下:
图5 App业务组件划分
//集成开发模式
apply plugin:’com.android.library’
//组件开发模式,可以独立运行
apply plugin:’com.android.application’
(2) 核心路由组件。在Android中,通过startActivity来实现页面间的跳转。但是根据组件化遵循的原则,业务组件按照功能模块进行拆分解耦之后是不能相互依赖的,那么核心路由组件就可以解决组件之间通信跳转的问题。路由的定义是通过网络把信息从源地址传输到目的地址的过程[6]。组件化之后所有页面跳转必须通过定义的资源标识符来实现,因此可以为每个页面定义一个统一的资源标识符,在网络中能够被其他页面访问,从而实现不同组件的通信跳转。业界主流的路由框架包括阿里的ARouter和美团的WMRouter。
2.2.4宿主层
宿主层(App壳工程)集成普通业务组件,它包含两个配置,分别为组件依赖配置和多渠道配置,没有任何代码逻辑。开发者可以根据组件依赖配置,选择普通业务组件到宿主层中,同时依据多渠道配置生成不同应用ID的App。通过上述配置,可以达到一套代码管理生成多个App应用的目的。
(1) 组件依赖配置。Android Studio采用Gradle构建项目,创建Android项目时会在宿主层App下生成build.gradle配置文件(其他组件类似),其支持自定义构建配置,包括组件依赖的配置。
(2) 多渠道配置。多渠道打包能为应用市场个性化的要求实现更深度的定制,包括生成不同应用ID、应用图标和启动页等,实现一套代码生成多个个性化App应用的目的,其配置依然是在宿主层App下的build.gradle中。
2.3 基础库和版本管理
在组件化实施过程中,不同组件依赖的SDK版本不一致或者引入的第三方库版本不一致则会导致兼容性问题而使项目无法编译[5]。在此,引入配置文件config.xml对基础库与版本集中管理,同时通过脚本配置完成组件对配置文件的依赖,达到每个组件依赖的SDK版本和第三方库版本一致的目的。
3 应用程序实例
按照上述组件化开发框架设计,完成了测试工程的基本搭建。项目工程包括一个App壳工程(含多渠道配置和组件依赖配置)、普通业务组件层commonBusinessModule(含路由组件框架)、移动端基础中台(含基础业务组件baseBusinessModule和基础功能组件baseFunctionModule),工程项目结构如图6所示。
图6 移动端组件化项目结构图
测试程序以壳工程App下面的Activity为主界面,分别对App、普通业务组件loginModule和orderModule进行开发测试,修改config.gradle和gradle.properties中的全局配置变量。
(1) 多渠道配置测试。实现定制不同应用ID、不同logo、不同名称等的App。修改壳工程App下的build.gradle渠道配置,同时在壳工程App/src目录之下新建对应渠道的名称(和build.gradle中名称一致),然后在渠道目录之下新建res资源文件(和main下的res一样),用于定制不同应用App的logo、启动页等资源。
多渠道打包效果图如图7所示。
图7 多渠道的资源配置示意图和打包效果图
(2) 组件依赖配置测试。修改gradle.properties中的全局配置变量为:
isNeedLoginModule=false
isNeedOrderModule=false
即可单独编译loginModule和orderModule组件。
项目工程已由集成模式变为组件模式打包,如图8所示。
图8 集成模式转组件模式打包示意图
(3) 路由功能测试。本测试工程使用阿里的ARouter路由框架。为每个普通业务组件的启动窗口添加如下注解代码,如loginModule组件的路由路径为:@Route(path=“路由地址常量”),控件点击触发路由跳转部分代码如下:
ARouter.getInstance().build(“路由地址”).navigation()
需要注意的是,由于Android的API14后,组件开发中的资源不再是常量[10],因此,对于多个控件的监听需要由switch-case转为if-else if-else结构。
测试由壳App跳转到loginModule组件和orderModule组件(如图9所示),orderModule组件跳转到loginModule组件(如图10所示)。
图9 由壳App跳转到组件一
图10 由组件一跳转到组件二
(4) 整体测试。本测试包括把所有组件以集成模式打包成一个App;把所有组件单独编译生成独立的App。
修改gradle.properties中的组件全局配置变量,通过编译得到一个由组件组合的完整App应用,如图11所示。图11中前三个App由组件组合编译而成(包括多渠道的定制配置,如logo、名称),最后两个App是由loginModule组件和orderModule组件单独编译生成。
图11 集成模式打包和组件模式打包的APK
4 结 语
总之,随着移动互联网技术的发展,人们对Android系统应用软件的研发也提出了更高的要求,在保证应用软件功能实现的基础上,合理地对开发框架进行优化,可以提升开发系统的使用效率、提高代码的复用率。因此,这种组件化开发框架在移动互联网产业开发中具有很高的实用价值,不仅能够有效提高个人和企业开发效率,提升应用软件价值,更能为互联网企业创造更高的效益和利润。