All Products
Search
Document Center

Mobile Platform as a Service:Portal and Bundle projects

Last Updated:Jun 10, 2026

The mPaaS component-based framework uses OSGi to split an Android app into independent Bundle projects and one Portal project that merges them into a runnable APK.

Important
  • If you use baseline 10.2.3 or later, use the native AAR method.

  • The component-based connection type (Portal & Bundle) requires Android Studio Flamingo (2022.2.1) or an earlier version.

The component-based framework uses OSGi technology to divide an app into one or more business-independent Bundle projects and one Portal project. mPaaS manages the lifecycle and dependencies of each Bundle, and the Portal merges all Bundle packages into a runnable .apk package.

This framework suits team-based app development. It provides component initialization and instrumentation for easy mPaaS integration.

Bundle projects

A traditional native project has a main module and optional sub-modules. An mPaaS Bundle project typically has a main module named app and several sub-modules.

For example, in Alipay, a Bundle has a main module named app and three sub-modules:

  • api: Contains only interface definitions.

  • biz: Contains implementations of the interfaces.

  • ui: Contains activities, custom views, and other UI-related components.

Note

A Bundle must have at least one sub-module named api. Without it, the Bundle cannot generate an interface package, and other Bundles cannot depend on it.

Bundle projects cover the following aspects:

Differences between Bundle and traditional projects

A Bundle is essentially a native project. The key difference is that the mPaaS Apply plugin is added to the build.gradle files of the project, main module, and sub-modules:

  • The build.gradle file in the project root directory

  • The build.gradle file of the main module

  • The build.gradle file of a sub-module

build.gradle in the project root directory

Add a dependency on the mPaaS plugin in the root build.gradle file:

Note

The plugin version may change with new iterations.

classpath 'com.alipay.android:android-gradle-plugin:3.0.0.9.13'

image.png

build.gradle of the main module

Declare the mPaaS Bundle Apply plugin in the main module's build.gradle file to mark the project as a Bundle:

apply plugin: 'com.alipay.bundle'

The main module's build.gradle file also includes the following configuration:image

Parameters:

  • version: The Bundle version.

  • group: The Bundle group ID.

  • exportPackages: The package names containing all classes of this Bundle. You can specify a parent package name. For non-statically-linked Bundles, exportPackages is required — otherwise, classes may fail to load. For example, if all code is under com.alipay.demo and com.alipay.bundle, specify com.alipay in exportPackages, or specify both com.alipay.demo and com.alipay.bundle. Avoid overly generic or overly specific package names.

  • initLevel: The Bundle loading priority at startup. Range: 0–100 (lower = earlier). A value of 11110000 enables lazy loading (loaded on demand).

  • packageId: The resource ID for aapt packaging. Must be unique per Bundle in a multi-Bundle architecture. The packageIds used by mPaaS are:

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

The following mPaaS dependencies are added 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 a sub-module

Declare the mPaaS Apply plugin in the sub-module's build.gradle file to mark it as a Bundle sub-module. This creates the Bundle's interface package.

apply plugin: 'com.alipay.library'

mPaaS dependencies 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

Bundle properties in this framework are based on OSGi Bundles but simplified.

The following table lists the Bundle properties.

Property

Description

Bundle-Name

Derived from the group in build.gradle and the name in settings.gradle.

Bundle-Version

From the version in build.gradle.

Init-Level

From the init.level in build.gradle.

Package-Id

From the properties in build.gradle.

Contains-Dex

Whether the Bundle contains a DEX file. Determined automatically by the compile plugin.

Contains-Res

Whether the Bundle contains resources. Determined automatically by the compile plugin.

Native-Library

The .so files in the Bundle. Determined automatically by the compile plugin.

Component-Name

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

exportPackages

The package names containing all classes of this Bundle. Defined in the main module's build.gradle file.

Bundle interface packages

A Bundle can contain multiple sub-modules (biz, api, ui). When compiled, each sub-module generates an interface package in .jar format. Other Bundles can use the api interface package.

Compilation also generates a Bundle project package containing all sub-modules. The Portal uses this project package to build the final .apk.

  • A Bundle sub-module's interface package contains only Java or Kotlin interface classes — no other resources (such as res directory content). Only sub-modules named api generate these interface packages.

  • Bundles depend on each other through interface packages. Configure the dependency in the dependency section of the Bundle's build.gradle file. For example, if Bundle A depends on the bapi sub-module in Bundle B, add the bapi dependency in the dependency section of the corresponding sub-module's build.gradle:

    provided "com.alipay.android.phone:bundleB:1.0.1:bapi@jar"
  • The groupId:artifactid:version:classifier in the dependency corresponds to the group, name, version, and sub-module name declared in the Bundle.

  • By default, the Bundle name is the main module's folder name. You can change it in settings.gradle. In this example, app is the main module's project name:

    include ':api', ':xxxx-build'
    project(':xxxx-build').projectDir = new File('app')

Bundle project packages

  • The .jar package from the entire Bundle project is actually an .apk-format file with a .jar extension (for example, framework-build.jar).

  • To depend on a Bundle in a Portal, declare the dependency in the dependency section of the Portal's main module build.gradle:

    dependencies {
        bundle "com.alipay.android.phone.mobilesdk:framework-build:version@jar"
        manifest "com.alipay.android.phone.mobilesdk:framework-build:version:AndroidManifest@xml"
    }
  • Bundle packages come in debug and release types. To depend on a debug package, append :raw to the dependency.

    • When the Portal depends on the Bundle's debug package: bundle "com.alipay.android.phone.mobilesdk:framework-build:version:raw@jar"

    • When the Portal depends on the Bundle's release package: bundle "com.alipay.android.phone.mobilesdk:framework-build:version@jar"

Note
  • When packaging a Portal, determine:

    • Which Bundles to package into the main DEX. Statically linked Bundles containing a ContentProvider must be included.

    • Which Bundles to load dynamically. For small apps, package all Bundles in the main DEX.

  • To package a Bundle's code into the main DEX, add it to the Portal's slinks file in the format groupId-artifactId. If the artifactId ends with -build, remove the suffix. For example, for groupId com.mpaas.group and artifactId testBundle-build, add com.mpaas.group-testBundle to slinks.

  • Static linking packages the Bundle's code into the APK's classes.dex, classes1.dex, classes2.dex, and other DEX files, enabling classes to load at startup.

Portal projects

A Portal project merges all Bundle packages into a runnable .apk.

Differences between Portal and traditional projects

A Portal differs from a traditional project in the build.gradle file:

  • build.gradle in the project root directory

  • build.gradle in the main module directory

build.gradle in the project root directory

The com.alipay.android:android-gradle-plugin:2.1.3.2.7 plugin is added to the classpath:

Note

The plugin version may change with new iterations.

image.png

This plugin includes the Portal plugin, which merges Bundles during packaging.

  • Merged .jar bundle

  • Merging the bundle's AndroidManifest

build.gradle in the main module directory

Declare the mPaaS Apply Portal plugin to mark the project as a Portal:

apply plugin: 'com.alipay.portal'

Add the Bundle dependencies to the dependencies block. The statements in dependencies declare the bundles and manifests that the Portal depends on:

image

Important
  • Typically, you do not write code in a Portal.

  • The following Bundle resources must be placed in the Portal. Otherwise, they cannot be found during compilation or at runtime:

    • Resources used in AndroidManifest.xml.

    • Resources passed to NotificationManager.

    • Resources used through the getResources().getIdentifier() method.

    • If a third-party AAR package contains any of these resource types, decompress the AAR and copy the resources to the Portal.

Project dependencies

An mPaaS-based app includes one Portal and one or more Bundles. Each app can have only one Portal but multiple Bundles.

The mPaaS plugin merges all Bundle packages in the Portal into a runnable .apk. After merging, the plugin deploys the Bundle to a repository. The repository address is defined in the Bundle's main module build.gradle:

uploadArchives {
    repositories {
        mavenLocal()
    }
}

By default, this uploads to the local ~/.m2 repository. You can add a custom repository address:

mavenDeployer {
    mavenLocal()
    repository(url: "${repository_url}") {
        authentication(userName: 'userName', password: 'userName_pwd')
    }
    snapshotRepository(url: "${repository_url}") {
        authentication(userName: 'userName', password: 'userName_pwd')
    }
}

After uploading, the Bundle is available in the format groupid:artifactid:version:classifier@type. Declare dependencies in the dependency section of the Portal's main module build.gradle:

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'
}

For dependencies between Bundles, declare the repository address in the dependent Bundle's root build.gradle.

Important

The username and password below are not your console logon credentials. To obtain these values, join the DingTalk group 145930007362.

  • mavenLocal(): The local repository for dependencies.

  • maven{}: The remote repository for dependencies.

allprojects {
    repositories {
        mavenLocal()
        mavenCentral()
        maven {
            credentials {
                username "{username}"
                password "{password}"
            }
            url "http://mvn.cloud.alipay.com/nexus/content/repositories/releases/"
        }
    }
}

Bundle compilation and packaging results

Compiling and packaging a Bundle with the mPaaS plugin generates a project package (.jar). For more information, see Bundle project packages and Bundle interface packages.

The project package is published to the repository in groupid:artifactid:version:classifier@type format. The repository address is defined in the Bundle's main module build.gradle:

uploadArchives {
    repositories {
        mavenLocal()
    }
}

This uses the local Maven repository (mavenLocal, default: ~/.m2). To change the address or add a repository, see Configure a publishing repository.

Add Bundle dependencies

You can add a Bundle dependency from within a Portal or from another Bundle:

  1. Declare the dependency repository in the root build.gradle of the Portal or Bundle. The dependency repository must match the Bundle's publishing repository. Configure a dependency repository.

  2. Declare dependencies in the main module's build.gradle. The following example adds a dependency on the quinox 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'
}

Related topics