加载框架与定制

mPaaS Android 框架提供了一整套的加载逻辑。基于此框架,研发团队可以进行多业务线开发。本文描述框架的启动流程以及如何在框架下添加自己的代码以对接启动。

启动流程

Application

传统 Android apk 运行时首先加载 AndroidManifest 文件 application 节点中 android:name 配置的 Application。

由于 mPaaS Android 框架重写了加载流程, android:name 中配置 mPaaS Android 框架的 com.alipay.mobile.quinox.LauncherApplication 类。

<application
    android:name="com.alipay.mobile.quinox.LauncherApplication"
    android:allowBackup="true"
    android:debuggable="true"
    android:hardwareAccelerated="false"
    android:icon="@drawable/appicon"
    android:label="@string/name"
    android:theme="@style/AppThemeNew" >
</application>

启动页

由于框架加载 bundle 可能会比较耗时,因此需要一个启动页等待框架启动完成之后再跳转到程序主页,所以在 AndroidManifest 文件中配置了框架提供的 com.alipay.mobile.quinox.LauncherActivity 应用启动页。

配置如下:

<activity
android:name="com.alipay.mobile.quinox.LauncherActivity"
android:configChanges="orientation | keyboardHidden | navigation"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateAlwaysHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

为方便开发人员对启动过程的理解,也为了避免启动过程被误改误删、被干扰,mPaaS 的启动过程被适度封装。因此,上述的 LauncherApplicationLauncherActivity 对开发人员完全不可见。

为了让客户端 App 在启动过程中实现自身的初始化逻辑,mPaaS 设计了 LauncherApplicationAgentLauncherActivityAgent 代理。作为开发人员,您可以通过继承这两个类,在相应的回调中实现自身的初始化逻辑。当您在 bundle 工程中定义了这两个类时,在使用 ProGuard 进行代码混淆的时候则需要对这两个类进行防混淆设置,详情请参见 混淆 Android 文件

启动流程图

mPaaS Android 框架加载流程如下:2

  1. 框架启动后主线程会创建启动页 LauncherActivity ,然后回调 LauncherActivityAgentpreInit 方法。

  2. 框架进行 multidex。过程中会回调 LauncherApplicationAgentpreInit 方法,读取当前 .apk 中每个 bundle 的描述文件,并对每个 bundle 创建对应的类加载器,加载其中的资源文件。

  3. 初始化完成后,回调 LauncherActivityAgentLauncherApplicationAgentpostInit 方法。

定制

实际上,框架已在 Launcher 工程中自动创建了两个类 MockLauncherApplicationAgentMockLauncherActivityAgent 继承了 LauncherApplicationAgentLauncherActivityAgent 这两个回调接口。在框架的初始化过程中,它们分别在 LauncherApplictionLauncherActivity 中被调用。

在 Portal 的 AndroidManifest.xml 中配置如下。开发人员也可在 Bundle 中实现这两个代理类,在以上配置中修改对应 meta-datavalue 值:

     <application
          android:name="com.alipay.mobile.quinox.LauncherApplication" >

         <!-- Application 的回调配置 -->
         <meta-data
            android:name="agent.application"
            android:value="com.mpaas.demo.launcher.framework.MockLauncherApplicationAgent"/>

        <!-- Activity 的回调配置 -->
        <meta-data
            android:name="agent.activity"
            android:value="com.mpaas.demo.launcher.framework.MockLauncherActivityAgent"/>
        <!-- 启动页的布局配置 -->
        <meta-data
            android:name="agent.activity.layout"
            android:value="layout_splash"/>

     </application>

代理类

agent.application 配置的是启动过程代理 ApplicationAgent,如下所示:

  public class MockLauncherApplicationAgent extends LauncherApplicationAgent {
      @Override
      protected void preInit() {
          super.preInit();
          //框架初始化前
      }

      @Override
      protected void postInit() {
          super.postInit();
          //框架初始化后
      }
  }

客户端 App 可以在 LauncherApplicationAgent 的实现类中,进行一些 Application 级别的初始化工作。preInit() 回调发生在框架初始化之前,因此不要在这里调用框架(MicroApplicationContext)的相关接口。而 postInit() 回调发生在框架初始化完成之后,是可以使用的。

agent.activity 配置的是启动 Activity 的代理,如下所示:

public class MockLauncherActivityAgent extends LauncherActivityAgent {

        @Override
        public void preInit(Activity activity) {
                super.preInit(activity);
                //Launcher Activity 启动前
        }

        @Override
        public void postInit(final Activity activity) {
            super.postInit(activity);
                //Launcher Activity 启动后
                //跳转程序首页的逻辑
                startActivity(activity,YOUR_ACTIVITY);
        }
}

同上述的 LauncherApplicationAgent 类似,LauncherActivityAgent 的两个回调也分别发生在框架初始化之前和之后,使用方法也类似。

修改启动页布局

在 Portal 的 AndroidManifest.xml 中还配置了启动页的布局文件,如下所示:

<application
android:name="com.alipay.mobile.quinox.LauncherApplication" >
<!-- 启动页的布局配置 -->
<meta-data
android:name="agent.activity.layout"
android:value="layout_splash"/>

</application>

修改 value 值为自定义的布局文件名。

说明

需要把布局文件和引用的相关资源放置在 Portal 工程里。

相关链接

代码示例