All Products
Search
Document Center

Mobile Platform as a Service:Register general components

Last Updated:Feb 06, 2026

Modularity is a key design principle of the mPaaS framework. Business modules with low coupling and high cohesion are easier to extend and maintain.

Business modules exist as Bundles and do not affect each other. However, Bundles can be related. For example, you might navigate to another Bundle's UI, call an API in another Bundle, or need to complete certain operations during initialization.

For this reason, mPaaS provides a `metainfo` universal component registration mechanism. Each Bundle declares the components it registers in the metainfo.xml file.

The framework currently supports the following components:

  • ActivityApplication

  • ExternalService (Service)

  • BroadcastReceiver

  • Pipeline

The metainfo.xml file has the following format:

<?xml version="1.0" encoding="UTF-8"?>
<metainfo>
    <broadcastReceiver>
        <className>com.mpaas.demo.broadcastreceiver.TestBroadcastReceiver</className>
        <action>com.mpaas.demo.broadcastreceiver.ACTION_TEST</action>
    </broadcastReceiver>
    <application>
        <className>com.mpaas.demo.activityapplication.MicroAppEntry</className>
        <appId>33330007</appId>
    </application>
</metainfo>

Application component

The ActivityApplication is a component designed by the mPaaS framework to act as an Activity container for managing and organizing Activities. It is used to handle navigation to the UI of another Bundle. This allows the caller to perform the navigation by only knowing the ActivityApplication information registered in the framework and the agreed-upon parameters.

About this task

The mPaaS framework fully manages the lifecycle of an ActivityApplication, including its creation and destruction. Your business logic only needs to process the received parameters and manage the Activities within its scope. This effectively isolates your business logic from the caller. The business logic and the caller only need to agree on the call parameters, which creates a more lightweight dependency.

For Android client applications developed with the mPaaS framework, Activities must inherit from `BaseActivity` or `BaseFragmentActivity` so they can be managed by the `ActivityApplication` class.

Procedure

  1. In the main module of the project, create a metainfo.xml file in the location shown in the following figure:

  2. Add the following configuration to metainfo.xml:

    • The `className` attribute specifies the class that handles navigation and defines the behavior for each stage. For the class definition, see the code in step 3. The framework uses this name to load the corresponding class. Therefore, this class must not be obfuscated and must be kept in the obfuscation file.

    • `appId`: This is the unique identifier for the business. To perform the navigation, the caller only needs to know the `appId` of the business. The framework layer handles the mapping between the appId and the `ActivityApplication`.

      <?xml version="1.0" encoding="UTF-8"?>
      <metainfo>
        <application>
            <className>com.mpaas.demo.hotpatch.HotpatchMicroApp</className>
            <appId>33330002</appId>
        </application>
      </metainfo>
  3. If the class specified by `className` only performs a simple navigation, you can use the following code for the implementation:

     /**
      * Scenario 1:
      * If you only need to navigate to a specific Activity interface, you must override getEntryClassName and onRestart. The former returns the class name of the Activity. The latter needs to call getMicroApplicationContext().startActivity(this, getEntryClassName()).
      * Scenario 2:
      * To navigate to different Activity interfaces based on requirements, you must override onStart and onRestart. Navigate to the specified interface based on the parameters in the bundle.
      * Created by mengfei on 2018/7/23.
      */
     public class MicroAppEntry extends ActivityApplication {
    
         @Override
         public String getEntryClassName() {
             // Scenario 1: If you can only navigate to a specific Activity, return the class name here.
             // Scenario 2: If you navigate to an interface based on parameters, you need to return null.
             return MainActivity.class.getName();
         }
    
         /**
          * This method is called when the Application is created. The implementation class can perform some initialization work here.
          *
          * @param bundle
          */
         @Override
         protected void onCreate(Bundle bundle) {
             doStartApp(bundle);
         }
    
         /**
          * This method is called when the Application starts.
          * If the Application has not been created, the create method is executed first, and then the onStart() callback is executed.
          */
         @Override
         protected void onStart() {
         }
    
         /**
          * This callback is invoked when the Application is destroyed.
          *
          * @param bundle
          */
         @Override
         protected void onDestroy(Bundle bundle) {
    
         }
    
         /**
          * When the Application starts, if it has already been started, the onRestart() callback is invoked instead of onStart().
          *
          * @param bundle
          */
         @Override
         protected void onRestart(Bundle bundle) {
         // For Scenario 1: You need to call getMicroApplicationContext().startActivity(this, getEntryClassName()) here.
             doStartApp(bundle);
         }
    
         /**
          * When a new Application is started, the current Application is paused, and this method is called back.
          */
         @Override
         protected void onStop() {
    
         }
    
         private void doStartApp(Bundle bundle) {
             String dest = bundle.getString("dest");
             if ("main".equals(dest)) {
                 Context ctx = LauncherApplicationAgent.getInstance().getApplicationContext();
                 ctx.startActivity(new Intent(ctx, MainActivity.class));
             } else if ("second".equals(dest)) {
                 Context ctx = LauncherApplicationAgent.getInstance().getApplicationContext();
                 ctx.startActivity(new Intent(ctx, SecondActivity.class));
             }
         }
     }
  4. The caller can navigate using the interface provided in MicroApplicationContext, which is encapsulated by the framework. The curId parameter can also be `null`:

     // Get the MicroApplicationContext object:
     MicroApplicationContext context = MPFramework.getMicroApplicationContext();
     String curId = "";
     ActivityApplication curApp = context.getTopApplication();
      if (null != curApp) {
          curId = curApp.getAppId();
     }
     String appId = "ID of the target ApplicationActivity";
     Bundle bundle = new Bundle(); // Optional additional parameters
     context.startApp(curId, appId, bundle);

Service component

mPaaS provides the Service component to enable cross-Bundle interface calls. A Service component provides logic as a service for other modules to use.

About this task

The Service component has the following features:

  • No user interface restrictions.

  • Designed to separate the interface from the implementation.

By design, only the interface class is visible to the caller. Therefore, define the interface class in the interface module. When you generate a Bundle project, an interface module named `api` is created by default. Define the implementation in the main module.

External calls are made through the findServiceByInterface interface of MicroApplicationContext to retrieve the corresponding service using the interfaceName. For Bundles, only the abstract service interface class is exposed. This class is specified in `interfaceName` and defined in the interface package.

Procedure

Register the Service component as follows:

  1. Define the location of metainfo.xml as shown in the following figure:

  2. Add the following configuration to metainfo.xml. The framework uses interfaceName as the key and className as the value to create a mapping. The className attribute specifies the implementation class of the interface, and interfaceName specifies the abstract interface class:

    <metainfo>
     <service>
         <className>com.mpaas.cq.bundleb.MyServiceImpl</className>
         <interfaceName>com.mpaas.cq.bundleb.api.MyService</interfaceName>
         <isLazy>true</isLazy>
     </service>
    </metainfo>
    • The abstract interface class is defined as follows:

      public abstract class MyService extends ExternalService {
        public abstract String funA();
      }
    • The interface class implementation is defined as follows:

      public class MyServiceImpl extends MyService {
        @Override
        public String funA() {
            return "This is the interface provided by BundleB by service";
        }
      
        @Override
        protected void onCreate(Bundle bundle) {
      
        }
      
        @Override
        protected void onDestroy(Bundle bundle) {
      
        }
      }
    • The external call method is as follows:

      MyService myservice = LauncherApplicationAgent.getInstance().getMicroApplicationContext().findServiceByInterface(MyService.class.getName());
      myservice.funA();

BroadcastReceiver component

`BroadcastReceiver` is an encapsulation of android.content.BroadcastReceiver. The difference is that the mPaaS framework uses android.support.v4.content.LocalBroadcastManager to register and unregister the `BroadcastReceiver`. Therefore, these broadcasts are only used within the current application. In addition, the mPaaS framework has a series of built-in broadcast events that you can listen to.

About this task

mPaaS built-in broadcast events

mPaaS defines a variety of broadcast events, which are mainly used to monitor the status of the current application. The process of registering a listener is the same as in native development. However, note that these statuses can only be monitored in the main process. The following is sample code: 示例代码 The following are the built-in broadcast events:

public interface MsgCodeConstants {
    String FRAMEWORK_ACTIVITY_CREATE = "com.alipay.mobile.framework.ACTIVITY_CREATE";
    String FRAMEWORK_ACTIVITY_RESUME = "com.alipay.mobile.framework.ACTIVITY_RESUME";
    String FRAMEWORK_ACTIVITY_PAUSE = "com.alipay.mobile.framework.ACTIVITY_PAUSE";
    // Broadcast for user leaving, pushing to background broadcast
    String FRAMEWORK_ACTIVITY_USERLEAVEHINT = "com.alipay.mobile.framework.USERLEAVEHINT";
    // Broadcast for all Activities being stopped. This may mean pushing to the background, but the same judgment logic is not currently used.
    String FRAMEWORK_ACTIVITY_ALL_STOPPED = "com.alipay.mobile.framework.ACTIVITY_ALL_STOPPED";
    String FRAMEWORK_WINDOW_FOCUS_CHANGED = "com.alipay.mobile.framework.WINDOW_FOCUS_CHANGED";
    String FRAMEWORK_ACTIVITY_DESTROY = "com.alipay.mobile.framework.ACTIVITY_DESTROY";
    String FRAMEWORK_ACTIVITY_START = "com.alipay.mobile.framework.ACTIVITY_START";
    String FRAMEWORK_ACTIVITY_DATA = "com.alipay.mobile.framework.ACTIVITY_DATA";
    String FRAMEWORK_APP_DATA = "com.alipay.mobile.framework.APP_DATA";
    String FRAMEWORK_IS_TINY_APP = "com.alipay.mobile.framework.IS_TINY_APP";
    String FRAMEWORK_IS_RN_APP = "com.alipay.mobile.framework.IS_RN_APP";
    // Broadcast for user returning to the foreground
    String FRAMEWORK_BROUGHT_TO_FOREGROUND = "com.alipay.mobile.framework.BROUGHT_TO_FOREGROUND";
}

Custom broadcast events

  1. Define the location of metainfo.xml as shown in the following figure:

  2. Add the following configuration to metainfo.xml:

     <?xml version="1.0" encoding="UTF-8"?>
     <metainfo>
         <broadcastReceiver>
             <className>com.mpaas.demo.broadcastreceiver.TestBroadcastReceiver</className>
             <action>com.mpaas.demo.broadcastreceiver.ACTION_TEST</action>
         </broadcastReceiver>
     </metainfo>
    • Custom Receiver implementation

      public class TestBroadcastReceiver extends BroadcastReceiver {
        private static final String ACTION_TEST = "com.mpaas.demo.broadcastreceiver.ACTION_TEST";
      
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_TEST.equals(action)) {
                //TODO
            }
        }
      }
    • Send broadcast

      LocalBroadcastManager.getInstance(LauncherApplicationAgent.getInstance().getApplicationContext()).sendBroadcast(new Intent("com.mpaas.demo.broadcastreceiver.ACTION_TEST"));

Pipeline component

The mPaaS framework has a distinct startup process. The Pipeline mechanism allows a line-of-business to encapsulate its running logic into a `Runnable` and add it to the Pipeline. The framework starts the Pipeline at the appropriate stage.

The following are the defined Pipeline timings:

  • com.alipay.mobile.framework.INITED: This indicates that framework initialization is complete. This event is triggered when the process starts and the framework is initialized in the background.

  • com.alipay.mobile.client.STARTED: This indicates that the client has started to launch. This event is triggered before the UI, such as the welcome screen, is displayed.

  • com.alipay.mobile.TASK_SCHEDULE_SERVICE_IDLE_TASK: The lowest priority. Tasks with this timing are executed only when there are no other higher-priority operations.

Because the framework invokes the Pipeline, you only need to specify the appropriate timing in metainfo.

About this task

You can download a code sample that demonstrates this universal component. For download links, usage instructions, and important notes, see Get code sample.

Procedure

  1. Define the location of metainfo.xml as shown in the following figure:

  2. Add the following configuration to metainfo.xml:

     <?xml version="1.0" encoding="UTF-8"?>
     <metainfo>
         <valve>
             <className>com.mpaas.demo.pipeline.TestPipeLine</className>
             <!--pipelineName is used to specify the stage of execution-->
             <pipelineName>com.alipay.mobile.client.STARTED</pipelineName>
             <threadName>com.mpaas.demo.pipeline.TestPipeLine</threadName>
             <!--weight specifies the priority of the operation. The smaller the value, the higher the priority of execution.-->
             <weight>10</weight>
         </valve>
     </metainfo>
  3. Implement the Pipeline:

     public class TestPipeLine implements Runnable {
         @Override
         public void run() {
             //....
         }
     }