All Products
Search
Document Center

Mobile Platform as a Service:About Portal & Bundle projects

Last Updated:Oct 27, 2023

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.

Note

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 directory

  • build.gradle of the main module

  • build.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:

Note

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'
image.png

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:image

Where:

  • version: The version of the Bundle

  • group: The groupid of the Bundle

  • exportPackages: 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 enter exportPackages, otherwise there will be a problem that the class cannot be loaded. For example, if all the codes are under com.alipay.demo and com.alipay.bundle, then you can write com.alipay or com.alipay.demo, com.alipay.bundle in exportPackages. 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 group in the build.gradle file and the name </>defined in settings.gradle.

Bundle-version

Bundle version is from version in the build.gradle file.

Init-Level

The time to load the Bundle comes from the properties: init.level defined in the build.gradle file.

Package-Id

The packageid of the Bundle resource comes from the properties defined in the build.gradle file.

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 so files.

Component-Name

From the Activity,Service,BroadcastReceiver, and ContentProvider defined in the AndroidManifest.xml file.

exportPackages

For the name of the package where all the classes of this Bundle are located, see the build.gradle of the main module.

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 the build.gradle of the Bundle. For example, Bundle A depends on the bapi sub-module of Bundle B. Then you need to configure the dependency on bapi in the dependency in the build.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 in build.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"

  • Note

    When you pack the Portal package, you need to make sure the following items:

    • 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.

    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 directory

  • build.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:

Note

Due to the iteration of functions, the plug-in version may continue to increase.

image.png

This plug-in contains the Portal plug-in, which can merge the Bundles during the packing process.

  • Merge the .jar packages of Bundle

  • Merge 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:

image
    Important

    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:

    • 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.

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.

Note

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:

  1. 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.

  2. Declaredependencies in build.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'
     }