The component-based framework refers to the framework in which mPaaS divides an app into one or more Bundle projects and a Portal project based on Open Service Gateway Initiative (OSGi) technology. mPaaS manages the life cycle and dependencies of each Bundle project, and uses the Portal project to merge all Bundle project packages into a runnable .apk
package.
The mPaaS framework is suitable for teams to develop apps collaboratively, and the framework includes functions such as component initialization and embedding, so that you can easily access mPaaS components.
Bundle project
A traditional native project consists of a main module or a main module and several sub-modules. An mPaaS Bundle project generally consists of a main module named app and several sub-modules.
For example, in Alipay, a Bundle generally consists of a main module named app and the following three sub-modules:
api: pure code API, the definition of API interface.
biz: the implementation of API interface operation.
ui: such as activity, custom view.
There is at least one sub-module named api. If there is no sub-module, the API package of the Bundle cannot be packed. And the Bundle cannot be relied on by other Bundles.
After you read this topic, you will learn about the Bundle project from the following aspects:
Difference between Bundle projects and traditional projects
Bundle is essentially a native project. Compared to a native project, a Bundle project has an additional Apply plug-in of mPaaS in the build.gradle
of project, main Module, and sub-module. The specific differences are described as follows:
build.gradle
in project root directorybuild.gradle
of the main modulebuild.gradle
of the sub-module
build.gradle in project root directory
In build.gradle
in the project root directory, the dependency on the mPaaS plug-in is added:
Due to the iteration of functions, the plug-in version may continue to increase.
classpath 'com.alipay.android:android-gradle-plugin:3.0.0.9.13'
build.gradle of the main module
In build.gradle
of the main module, a declaration of mPaaS bundle Apply plug-in is added. This indicates that the project is a Bundle project. The Bundle configuration is as follows:
apply plugin: 'com.alipay.bundle'
The following configuration has been added to the main module build.gradle
:
Where:
version
: The version of the Bundlegroup
: The groupid of the BundleexportPackages
: Describes which package names all the classes of the current Bundle project are under. The package names can be a collection. For non-statically linked Bundles, you must enterexportPackages
, otherwise there will be a problem that the class cannot be loaded. For example, if all the codes are undercom.alipay.demo
andcom.alipay.bundle
, then you can writecom.alipay
orcom.alipay.demo, com.alipay.bundle
inexportPackages
. The package name can neither be too long nor too short.initLevel
: The time to load the Bundle when the framework starts. The timing range is 0-100. The smaller the number is, the earlier the loading occurs. Among them, 11110000 means loading during use, that is, lazy loading.packageId
: Describes the ID of the current Bundle resource, which is needed for aapt packing. Due to the multi-Bundle architecture, the packageId of each Bundle must be unique and cannot be the same as the packageId of other Bundles. The packageId currently used by mPaaS is as follows:
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 |
Add the following dependencies on mPaaS in dependencies
:
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.73@jar'
provided 'com.alipay.android.phone.thirdparty:androidsupport-api:13.23@jar'
}
build.gradle of the sub-module
In build.gradle
of the sub-module, a declaration of mPaaS Apply plug-in is added. This indicates that the project is a sub-module project of the Bundle, and the API package of this Bundle will eventually be packed.
apply plugin: 'com.alipay.library'
Add the following dependencies on mPaaS in dependencies
:
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 properties
The design concept of the Bundle property in this framework originates from the OSGi Bundle. But this design is more concise and lighter than the OSGi Bundle.
The following table lists the Bundle properties and descriptions:
Property | Description |
Bundle-Name | The Bundle name is from the |
Bundle-version | Bundle version is from |
Init-Level | The time to load the Bundle comes from the properties: |
Package-Id | The packageid of the Bundle resource comes from the properties defined in the |
Contains-Dex | Whether to include dex. This will automatically be determined by the compiler plug-in. |
Contains-Res | Whether to include resources. This will automatically be determined by the compiler plug-in. |
Native-Library | The compiler plug-in can automatically determine the included |
Component-Name | From the |
exportPackages | For the name of the package where all the classes of this Bundle are located, see the |
Bundle interface package
A Bundle may contain multiple sub-modules, such as biz, api, UI. When you compile and pack the Bundle, each sub-module will generate an interface package in the format of .jar
. Among these packages, only the API interface packages can be used by other Bundles.
At the same time, a Bundle project package is also generated during the packing. All sub-modules are contained in this project package. The project package can be used by the Portal project. The project package is compiled in the Portal and the .apk
package is generated finally.
The interface package packed by the sub-module of Bundle, only provides customized java/kotlin interface classes, excludes the resource under res directory. And these interface packages can only packed from the api modules.
Each Bundle project directly depends on each other through the API package of the Bundle. You need to configure the dependency API in the
dependency
in thebuild.gradle
of the Bundle. For example, Bundle A depends on thebapi
sub-module of Bundle B. Then you need to configure the dependency onbapi
in thedependency
in thebuild.gradle
of the corresponding sub-module of Bundle A.provided "com.alipay.android.phone:bundleB:1.0.1:bapi@jar"
The
groupId:artifactid:version:classifier
involved in the dependency corresponds to the group, name, version, and sub-module names declared in the Bundle.By default, the name of Bundle is the folder name of the main module. The Bundle name can be modified in
settings.gradle
, as shown in the following code, where app is the project name of the main module:include ':api', ':xxxx-build' project(':xxxx-build').projectDir = new File('app')
Bundle project package
The
.jar
package packed by the whole Bundle project, which is an.apk
file but the suffix is.jar
, for example,framework-build.jar
.To rely on Bundle in Portal, you need to declare the dependency on Bundle in
dependency
inbuild.gradle
of the main module of Portal, which is shown as follows:dependencies { bundle "com.alipay.android.phone.mobilesdk:framework-build:version@jar" manifest "com.alipay.android.phone.mobilesdk:framework-build:version:AndroidManifest@xml" }
There are two types of Bundle packages: debug package and release package. When Portal depends on the debug package of Bundle, you need to add
:raw to the debug package.
When Portal depends on the debug package of the Bundle, use
bundle "com.alipay.android.phone.mobilesdk:framework-build:version:raw@jar"
When Portal depends on the release package of the Bundle, use
bundle "com.alipay.android.phone.mobilesdk:framework-build:version@jar"
Which Bundles are to be packed in the main dex of the app. Static link. Bundle with
ContentProvider
must be placed in a static link.Which are dynamically loaded. If the app is not big, it is recommended to be packed in the main dex.
When you pack the Portal package, you need to make sure the following items:
If you want to pack the Bundle code into the main dex, you need to configure the current Bundle in the slinks
file of Portal. The configuration content is: groupId-artifactId
. If the configuration content ends with -build
, you need to remove -build. For example, if the groupId is com.mpaas.group
and the artifactId is testBundle-build
, you need to add a line in the slinks
file:com.mpaas.group-testBundle
.
Static link: Pack the Bundle code into classes.dex
in apk
, or into classes1.dex
or classes2.dex
. Then you can load the classes in the Bundle when the project starts.
Dynamic loading: Store the Bundle code in lib/armeabi
. When you use a Bundle class, the framework automatically creates a BundleClassLoader
for loading. In this case, you need to configure exportPackages
of the Bundle.
Portal project
The Portal project merges all the Bundle project packages into a runnable .apk
package.
Difference between Portal project and traditional project
The difference between Portal and traditional development projects is inbuild.gradle
:
build.gradle
in project root directorybuild.gradle
of the main module
build.gradle in project root directory
As shown in the following figure, the class path has an additional com.alipay.android:android-gradle-plugin:2.1.3.2.7
plug-in:
Due to the iteration of functions, the plug-in version may continue to increase.
This plug-in contains the Portal plug-in, which can merge the Bundles during the packing process.
Merge the
.jar
packages of BundleMerge the
AndroidManifest
file of Bundle
build.gradle of the main module
The declaration of mPaaS Apply Portal plug-in is added, which indicates that the project is a Portal project. The Portal configuration is as follows:
apply plugin: 'com.alipay.portal'
At the same time, add the corresponding dependency on Bundle in dependencies
. The statements in dependencies
are the declarations of Bundle and manifest, which are used to indicate which Bundles or manifests the Portal depends on:
Resources used in
AndroidManifest.xml
.The resources passed to
NotificaionManager
for use.Resources used by the
getResources().getIdentifier()
method.If there are the preceding three situations in the referenced third-party AAR package, you also need to decompress AAR and copy the corresponding resources into the Portal project.
Usually no code is written under Portal.
The following types of resources, such as style, drawable, and string, used in the Bundle project must be placed in the Portal project. Otherwise, the resources will not be found during compilation or runtime:
Project dependencies
An app based on the mPaaS framework includes one or more Bundles and a Portal. An app can have only one Portal project, but there can be multiple Bundle projects.
Through the mPaaS plug-in, the Portal project merges all the Bundle project packages into a runnable .apk
package. After the merge, the plug-in deploys the Bundle project to the specified library address. The library address is defined in build.gradle
in the main module of Bundle, as shown in the following code:
uploadArchives {
repositories {
mavenLocal()
}
}
The library address is uploaded to the local ~/.m2
library address. You can also add a custom library address as follows:
mavenDeployer {
mavenLocal()
repository(url: "${repository_url}") {
authentication(userName: 'userName', password: 'userName_pwd')
}
snapshotRepository(url: "${repository_url}") {
authentication(userName: 'userName', password: 'userName_pwd')
}
}
After the upload is completed, the Bundle is stored in the designated library in the form of groupid:artifactid:version:classifier@type
. So, if you declare dependency
in the build.gradle<
/>of the outermost main module of Portal, you can specify dependencies for each Bundle, as shown in the following code:
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'
}
In addition, the interdependence between Bundle projects also needs to declare the library dependency address in the outermost build.gradle
of the Bundle.
The username
and password
in the following configuration are not the logon user name and password of the console. Please search for group number 41708565 with DingTalk to join DingTalk group to get these two values.
mavenLocal()
describes the dependent local library address.maven{}
declares the address of the remote library that it depends on.
allprojects {
repositories {
mavenLocal()
mavenCentral()
maven {
credentials {
username "{username}"
password "{password}"
}
url "http://mvn.cloud.alipay.com/nexus/content/repositories/releases/"
}
}
}
Bundle compilation and packing results
After you compile and pack the package with the mPaaS plug-in, a Bundle will generate a project package, which is a .jar
package. For more information, see Bundle interface package and Bundle project package.
The project package will be published to the designated library in the form of groupid:artifactid:version:classifier@type
. The release library address is defined in build.gradle
in the Bundle main module as follows:
uploadArchives {
repositories {
mavenLocal()
}
}
The preceding configuration specifies that the release library is a local Maven library (mavenLocal
). If you need to modify the address of the local Maven library (default~/.m2
) or add a release library, see Configure release library.
Add Bundle dependencies
You can add Bundle dependencies to the Portal, or you can add dependencies to other Bundles. You only need to:
Declare the dependent library address in
build.gradle
at the outermost layer of Portal or Bundle. The dependent library needs to correspond to the preceding Bundle release library. For the configuration method of the dependent library, see Configure dependent library.Declare
dependencies
inbuild.gradle
of Portal or the main module of Bundle. An example of adding Bundle (quinox
) dependency is as follows: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' }