组件化框架 是指 mPaaS 基于 OSGi(Open Service Gateway Initiative,开放服务网关倡议)技术将把一个 App 划分成业务独立的一个或多个 Bundle 工程以及一个 Portal 工程的框架。mPaaS 会对每个 Bundle 工程的生命周期和依赖加以管理,使用 Portal 工程把所有的 Bundle 工程包合并成一个可运行的 .apk 包。
mPaaS 框架适合团队协同开发 App,并且该框架包含组件初始化、埋点等功能,方便您轻松接入 mPaaS 组件。
传统的原生工程由一个主模块或是一个主 module 和若干个子 module 组成,而一个 mPaaS Bundle 工程一般由一个名为 app 的主 module 和若干个子 module 组成。
例如,在支付宝中,一个 Bundle 一般由一个名为 app 的主 module 和以下三个子 module 组成:
通过阅读本文,您将从以下方面了解 Bundle 工程:
Bundle 本质上也是一个原生工程,只是在 工程、主 Module、子 Module 的 build.gradle
中多了 mPaaS 的 Apply 插件,具体差别体现在以下方面:
在工程根目录的 build.gradle
中,增加了对 mPaaS 插件的依赖:
重要:因功能迭代,插件版本可能会不断增加。
classpath 'com.alipay.android:android-gradle-plugin:3.0.0.9.13'
在主 module 的 build.gradle
中,增加了 mPaaS Bundle Apply 插件 的声明,表示该工程为 Bundle 工程,Bundle 配置如下:
apply plugin: 'com.alipay.bundle'
主 module 的 build.gradle
中还增加了以下配置:
其中:
version
:该 Bundle 的 version。group
:该 Bundle 的 groupid。exportPackages
: 描述当前 Bundle 工程所有的类在哪些包名下面,包名可以取合集。非静态链接的 Bundle 必须填写 exportPackages
,否则会出现类加载不到的问题。例如,如果所有的代码在 com.alipay.demo
和 com.alipay.bundle
下,那么在 exportPackages
中就可以写 com.alipay
,也可以写 com.alipay.demo,com.alipay.bundle
。包名不宜过长或过短。initLevel
:框架启动时加载该 Bundle 的时机。时机范围在 0-100,数字越小表示越早加载。其中 11110000 时为使用时加载,即懒加载。packageId
:描述当前 Bundle 的资源的 ID,供 aapt 打包时需要。由于是多 Bundle 架构,每个 Bundle 的 packageId 必须唯一,不可与其它 Bundle 的 packageId 重复。目前 mPaaS 已经使用的 packageId 如下:Bundle | packageId |
---|---|
com.alipay.android.phone.thirdparty:androidsupportrecyclerview-build | 28 |
com.alipay.android.phone.mobilesdk:framework-build | 30 |
com.alipay.android.phone.rome:pushservice-build | 35 |
com.alipay.android.phone.sync:syncservice-build | 38 |
com.alipay.android.phone.wallet:nebulabiz-build | 41 |
com.alipay.android.phone.mobilecommon:share-build | 42 |
com.alipay.android.phone.wallet:nebulacore-build | 66 |
com.alipay.android.mpaas:scan-build | 72 |
com.alipay.android.phone.wallet:nebula-build | 76 |
com.alipay.android.phone.securitycommon:aliupgrade-build | 77 |
在 dependencies
中会添加对 mPaaS 的如下依赖:
dependencies {
compile project(":api")
apt 'com.alipay.android.tools:androidannotations:2.7.1@jar'
//mPaaS dependencies
provided 'com.alipay.android.phone.thirdparty:fastjson-api:1.1.45@jar'
provided 'com.alipay.android.phone.thirdparty:androidsupport-api:13.23@jar'
}
在子 module 的 build.gradle
中,增加了 mPaaS Apply 插件 的声明,表示该工程为 Bundle 的 子 module 工程,最终会打出该 Bundle 的接口包。
apply plugin: 'com.alipay.library'
在 dependencies
中会添加对 mPaaS 的如下依赖:
dependencies {
apt 'com.alipay.android.tools:androidannotations:2.7.1@jar'
//mPaaS dependencies
provided "com.alipay.android.phone.thirdparty:utdid-api:1.0.3@jar"
provided "com.alipay.android.phone.mobilesdk:framework-api:2.1.1@jar"
}
本框架的 Bundle 属性设计思路参考 OSGi 的 Bundle,但比 OSGi 的 Bundle 更简洁和轻巧。
以下表格列出 Bundle 属性及其解释:
属性 | 解释 |
---|---|
Bundle-Name | Bundle Name,来自于由 build.gradle 文件中的 group 和 settings.gradle 中定义的 name 。 |
Bundle-Version | Bundle Version,来自于 build.gradle 文件中的 version 。 |
Init-Level | Bundle 的加载时机,来自于 build.gradle 文件中定义的 properties:init.level 。 |
Package-Id | Bundle 资源的 packageid,来自于 build.gradle 文件中定义的 properties。 |
Contains-Dex | 是否包含 dex,编译插件自动判断。 |
Contains-Res | 是否包含资源,编译插件自动判断。 |
Native-Library | 包含的 so 文件有哪些,编译插件自动判断。 |
Component-Name | 来自于 AndroidManifest.xml 文件中定义的 Activity ,Service ,BroadcastReceiver ,ContentProvider |
exportPackages | 该 Bundle 的所有的类所在的包名,参考主 module 的 build.gradle |
一个 Bundle 有可能包含多个 子 Module,如 biz, api, ui。在编译打包 Bundle 的时候,每个子 module 都会分别生成一个格式为 .jar
接口包,这些接口包可以被其他 Bundle 使用。
同时在打包的时候,也会生成一个 Bundle 工程包,这个工程包包含所有的子 module,工程包可以被 Portal 工程使用,工程包在 Portal 中编译,最后生成 .apk
包。
build.gradle
中的 dependency
配置依赖 api 接口。例如,Bundle A 依赖 Bundle B 中的 bapi
子 module,那么在 Bundle A 相应的子 module 的 build.gradle
中的 dependency
配置对 bapi
的依赖。
provided "com.alipay.android.phone:bundleB:1.0.1:bapi@jar"
groupId:artifactid:version:classifier
分别对应 Bundle 中声明的 group,name,version,子 module 的名字。settings.gradle
中修改,如下代码所示,其中 app 为主 module 的工程名:
include ':api', ':xxxx-build'
project(':xxxx-build').projectDir = new File('app')
.jar
包其实是一个 .apk
格式的文件,但是也以 .jar
结尾,如 framework-build.jar
。build.gradle
中的 dependency
中声明依赖 Bundle 包,如下所示:
dependencies {
bundle "com.alipay.android.phone.mobilesdk:framework-build:version@jar"
manifest "com.alipay.android.phone.mobilesdk:framework-build:version:AndroidManifest@xml"
}
:raw
bundle "com.alipay.android.phone.mobilesdk:framework-build:version:raw@jar"
bundle "com.alipay.android.phone.mobilesdk:framework-build:version@jar"
说明:
ContentProvider
的 Bundle 必须放在静态链接中。slinks
文件中配置当前 Bundle。配置内容为:groupId-artifactId
。如果以 -build
结尾,则去掉 -build。例如, groupId 为 com.mpaas.group
,artifactId 为 testBundle-build
,则需要在 slinks
文件中添加一行:com.mpaas.group-testBundle
。apk
的 classes.dex
或者 classes1.dex
, classes2.dex
等中,以便工程启动时就可以加载 Bundle 中的类。Portal 工程把所有的 Bundle 工程包合并成一个可运行的 .apk
包。
Portal 和传统开发中的工程的区别体现在 build.gradle
:
如下图所示,classpath 多了一个 com.alipay.android:android-gradle-plugin:2.1.3.2.7
插件 :
重要:因功能迭代,插件版本可能会不断增加。
该插件中包含 Portal 插件,Portal 插件可以在打包过程中把各 Bundle 合并。
.jar
AndroidManifest
多了 mPaaS Apply Portal 插件 的声明,表示该工程为 Portal 工程。Portal 配置如下:
apply plugin: 'com.alipay.portal'
同时,在 dependencies
中添加相应的对 Bundle 的依赖。dependencies
中的语句是 bundle 和 manifest 的声明,用来表示 Portal 依赖了哪些 Bundle 或 manifest:
注意:
AndroidManifest.xml
中使用的资源。getResources().getIdentifier()
方法使用的资源。aar
包中如有以上三种情况,也需要解压 aar
,将对应的资源复制一份放到 Portal 工程中。一个 基于 mPaaS 框架 的 App 包括 一个或多个 Bundle 和 一个 Portal。一个 App 有且只能有一个 Portal 工程,但可以有多个 Bundle 工程。
通过 mPaaS 插件,Portal 工程把所有的 Bundle 工程包合并成一个可运行的 .apk
包。合并后,该插件把 Bundle 工程部署至指定的仓库地址。该仓库地址在 Bundle 的主 module 中的 build.gradle
中定义,如下代码所示:
uploadArchives {
repositories {
mavenLocal()
}
}
该仓库地址是上传至本地的 ~/.m2
仓库地址。您也可以添加自定义的仓库地址,如下所示:
mavenDeployer {
mavenLocal()
repository(url: "${repository_url}") {
authentication(userName: 'userName', password: 'userName_pwd')
}
snapshotRepository(url: "${repository_url}") {
authentication(userName: 'userName', password: 'userName_pwd')
}
}
上传之后,Bundle 以 groupid:artifactid:version:classifier@type
的形式存在指定的仓库中。因此,只要在 Portal 最外层主 module 的 build.gradle
中声明 dependency
就可指定各 Bundle 依赖,如下代码所示:
dependencies {
bundle 'com.alipay.android.phone.mobilesdk:quinox-build:2.2.1.161221190158:nolog@jar'
manifest 'com.alipay.android.phone.mobilesdk:quinox-build:2.2.1.161221190158:AndroidManifest@xml'
}
此外,Bundle 工程之间的相互依赖也需要在 Bundle 的最外层的 build.gradle
中声明仓库依赖地址。
注意:以下配置中的 username
和 password
不是控制台的登录用户名和密码。您必须 提交工单 获取这两个值。其中,
mavenLocal()
是描述依赖的本地仓库地址。maven{}
声明依赖的远程仓库地址。
allprojects {
repositories {
mavenLocal()
mavenCentral()
maven {
credentials {
username "{username}"
password "{password}"
}
url "http://mvn.cloud.alipay.com/nexus/content/repositories/releases/"
}
}
}
使用 mPaaS 插件编译打包后,一个 Bundle 会生成一个工程包(是一个 .jar
包)。更多信息,请参考 Bundle 工程 > Bundle 工程包 和 Bundle 工程 > Bundle 接口包。
工程包会以 groupid:artifactid:version:classifier@type
的形式发布到指定仓库中。发布仓库地址在 Bundle 主 module 中的 build.gradle
中定义,示例如下:
uploadArchives {
repositories {
mavenLocal()
}
}
上述配置指定发布仓库为本地 Maven 仓库(mavenLocal
)。如需修改本地 Maven 仓库地址(默认 ~/.m2
)或增加发布仓库,请参见 配置发布仓库。
您可以在 Portal 中添加 Bundle 依赖,也可以在 Bundle 中添加其他 Bundle 依赖。只需:
build.gradle
中声明依赖仓库地址。依赖仓库应和上文 Bundle 发布仓库相对应。依赖仓库的配置方法,请参见 配置依赖仓库。build.gradle
中声明 dependencies
依赖。如添加 Bundle(quinox
)依赖的示例如下:
dependencies {
bundle 'com.alipay.android.phone.mobilesdk:quinox-build:2.2.1.161221190158:nolog@jar'
manifest 'com.alipay.android.phone.mobilesdk:quinox-build:2.2.1.161221190158:AndroidManifest@xml'
}
在文档使用中是否遇到以下问题
更多建议
匿名提交