传统的小程序技术容易受到网络环境影响,当网络质量不佳时可能导致拉取不到小程序包的情况。通过预置小程序,即可规避该问题。本文介绍了预置小程序的原理和预置小程序的实现过程。

 

什么是预置小程序

预置小程序是指将小程序的渲染、逻辑、配置等静态资源打包在一个压缩包内,客户端预先下载小程序包到本地、直接从本地加载资源的过程。预置小程序可以最大程度地摆脱网络环境对 mPaaS 小程序页面的影响。使用预置包能够为客户端带来以下优势:

  • 提升用户体验
    通过预置包的方式把页面内静态资源嵌入到应用中并随应用一起发布,可以使用户第一次开启应用时即无需依赖网络环境下载资源,可以直接开始使用。
  • 实现动态更新
    在推出新版本或紧急发布的时候,可以在小程序 IDE 中进行迭代开发,通过 mPaaS 控制台发布,客户端中集成的小程序 SDK 会自动将小程序更新到最新的版本。这种发布无需通过应用商店审核,可以让用户及早接收到更新。

 

预置小程序的实现原理

本文从以下方面介绍了预置小程序的实现原理:

  • 小程序预置包的结构
  • 小程序预置包的使用过程

小程预置包的结构

小程序预置包是一个 .amr 格式的压缩文件,将后缀 amr 改成 zip 解压缩后,可以看到其中包含的 HTML 资源和 JavaScript 代码等。待小程序容器加载后,这些资源和代码能在 UC 内核渲染。

以 Android 系统为例,下图显示了一般资源包的目录结构:

  • 一级目录:一般为资源包的 ID,如 2020121620201216_1.0.1.0.zip。
  • 二级目录及往后即为业务自定义的资源文件。并设定当前预置包默认打开的主入口文件,如 /index.html

小程序预置包的使用过程

使用小程序预置包的过程可以分为以下三个步骤:

  1. 请求包信息
    从服务端请求小程序包,并将小程序包信息存储到本地数据库的过程。包信息包含了小程序包的下载地址、小程序包版本号等。
  2. 下载小程序包
    把小程序包从服务端下载到手机。
  3. 安装小程序包
    下载目录,拷贝到手机安装目录。

 

前提条件

  • 已接入小程序组件。更多关于小程序组件的接入信息,请参见 快速开始使用小程序。
  • 已接入 H5 容器 组件。更多关于 H5 容器的接入信息,请参见 快速开始使用 H5 容器。

 

操作步骤-Android

  1. 预置小程序包。
    1. 在 mPaaS 控制台发布小程序包并下载 AMR 文件和配置文件。
    2. 将下载到的 AMR 文件和配置文件放置在 mPaaS 项目的 assets 目录下。
    3. 在工程中添加预置代码,以在应用启动时调用预置代码安装应用。预置代码示例如下:
new Thread(new Runnable(){    @Override    public void run(){        MPNebula.loadofflineNebula(jsonFileName: "h5_json.json",                                  new MPNebulaOfflineInfo(offLineFileName:"2020121620201216_1.0.1.0.amr",                                                         addId:"2020121620201216",                                                         version:"1.0.1.0"));    }}).start();

         

说明

    • 此方法为阻塞调用,请不要在主线程上调用内置预置包方法。
    • 此方法仅能调用一次。若多次调用,仅第一次调用有效。所以需要一次性传入所有需预置预置包信息。
    • 如果内置多个 AMR 包,需要要确保文件已存在;如不存在,会造成其他内置预置包失败。
  1. 启动小程序。启动小程序的示例代码如下。
/*** 启动小程序** @param appId 小程序id*/public static void startApp(String appId);

         

2. 更新小程序
默认情况下,每次打开应用,小程序 SDK 都会尝试检查是否有可更新的版本。出于服务端压力考虑,该检查有时间间隔限制,默认为 30 分钟。如果想立即检查最新可用版本,调用下方的代码来请求更新。一般情况下,可以在应用启动或者用户登录后调用。

MPNebula.updateAllApp(new MpaasNebulaUpdateCallback(){    @Override    public void onResult(final boolean success, final boolean isLimit) {        super.onResult(success, isLimit);        runOnUiThread(new Runnable() {            @Override            public void run() {                AUToast.makeToast(NebulaAppActivity.this,                        success ? R.string.update_success : R.string.update_failure, 2000).show();            }        });    }});

         

3. 校验安全签名
小程序具有签名校验机制,防止恶意程序篡改下载到设备的小程序包。通过调用 MPNebula 接口设置验签参数即可开启此机制。如果您使用的基线是 10.1.60 或以上版本,需要额外开启容器配置,详情参见 H5 容器配置。

说明

    • 请在第一次打开离线包前调用 MPNebula 接口,否则将会导致公钥初始化失败。关于公钥与私钥,参见 配置离线包 > 密钥管理。
    • 无论客户端是否开启签名校验,在被判断为 root 的手机上都会强制进行签名校验。
  /**   * @param publicKey 验签公钥   */  public static void enableAppVerification(final String publicKey)

         

4. 删除本地小程序
Nebula 提供了删除本地应用信息的接口。当本地应用信息被删除后,再次打开应用时会重新请求服务端下载、更新本地小程序的信息。

 public class MPNebula {    // appId 为离线包或小程序的应用 ID    public static boolean deleteAppInfo(String appId);}

         

说明:此 API 在 10.1.68 系列和 10.1.60 系列支持的最低基线版本分别为 10.1.68.8 和 10.1.60.14 。

 

操作步骤-iOS

  1. 预置小程序包。

a. 在 mPaaS 控制台发布小程序包并下载 AMR 文件和配置文件。

b. 新建一个独立的 bundle,如 DemoCustomPresetApps.bundle,将从发布平台下载的 .amr 离线包和 h5_json.json 文件添加到此 bundle 中。

重要:目前发布平台仅支持下载单个离线包的 h5_json.json 配置文件。当预置多个小程序包时,需要将不同 h5_json.json中的 data 数据手动合并到一个配置文件中。

c. 在初始化小程序时,在initNebulaWithCustomPresetApplistPath 接口,设置预置小程序离线包路径为上一步中创建的 bundle。

 - (void)application:(UIApplication *)application beforeDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions {     // 初始化 rpc     [MPRpcInterface initRpc];     // 初始化容器     //    [MPNebulaAdapterInterface initNebula];     // 自定义jsapi路径和预置小程序包信息     NSString *presetApplistPath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"DemoCustomPresetApps.bundle/h5_json.json"] ofType:nil];     NSString *appPackagePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"DemoCustomPresetApps.bundle"] ofType:nil];     NSString *pluginsJsapisPath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"DemoCustomPlugins.bundle/Poseidon-UserDefine-Extra-Config.plist"] ofType:nil];     [MPNebulaAdapterInterface initNebulaWithCustomPresetApplistPath:presetApplistPath customPresetAppPackagePath:appPackagePath customPluginsJsapisPath:pluginsJsapisPath]; }

         

2. 启动小程序

与非预置小程序类似,进入对应的页面时,调用 Nebula 容器提供的接口方法加载小程序。

[MPNebulaAdapterInterface startTinyAppWithId:@"2020121720201217" params:nil];

         

3. 更新小程序。

默认情况下,每次打开应用,小程序 SDK 都会尝试检查是否有可更新的版本。出于减少服务端压力的考虑,该检查有时间间隔限制,默认为 30 分钟。如果想立即检查最新可用版本,可调用下方的代码来请求更新。一般情况下,可以在应用启动或者用户登录后调用。

-(void)application:(UIApplication *)application afterDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions{        //全量更新本地小程序包信息    [[MPNebulaAdapterInterface shareInstance] requestAllNebulaApps:^(NSDictionary *data, NSError *error) {        NSLog(@"[mpaas] nebula rpc data :%@", data);    }];    }

         

4. 校验安全签名。

小程序具有签名校验机制,防止恶意程序篡改下载到设备的小程序包。通过调用 小程序 接口设置验签参数即可开启此机制。

说明

    • 请在第一次打开小程序包前调用 MPNebulaAdapterInterface 接口,否则将会导致公钥初始化失败。关于公钥与私钥,请参见 配置小程序包 > 密钥管理。
    • 开启验签
    [MPNebulaAdapterInterface shareInstance].nebulaNeedVerify = YES;

         

5. 删除本地小程序。

Nebula 提供了删除本地应用信息的接口。当本地应用信息被删除后,再次打开应用时会重新请求服务端下载、更新本地小程序的信息。

/** *  @brief 删除本地应用信息(包括包信息、amr以及安装目录) * *  @date 2019-02-28 * *  @return */-(void)clearAllAppInfo:(NSString *)appId;//使用方法[[NBServiceGet() appCenter] clearAllAppInfo:@"2020199503242811"];

         

 

结语

mPaaS 小程序源自于支付宝小程序框架,亿级线上业务体量的锤炼,安全性媲美支付宝原生能力。不仅面向自有 App 投放小程序,更可快速构建打包,覆盖支付宝、淘宝、钉钉等应用。

通过使用上述预置小程序的方案,预置小程序不仅可以最大程度地摆脱网络环境对 mPaaS 小程序页面的影响,还能深度体验用户体验、实现动态更新。

 

撰文:刘启洋、滕宏才

 

- END -


 

©著作权归作者所有:来自51CTO博客作者mPaaS的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 排查指南 | 当 mPaaS 小程序真机扫码时提示
  2. 排查指南 | mPaaS 小程序被卡在了三个蓝点
  3. 排查指南 | 当 mPaaS 小程序提示“应用更新错误(1001)”时
  4. 你为什么选择程序员这个职业?
  5. 当别人用月薪去衡量程序员时,我们自己应该谈点理想
  6. 假如程序员会武功?
  7. 理性思维VS中二晚期,二次元程序员调查报告
  8. 所有人都在渲染程序员的中年危机,我们却在劝你重新学会学习
  9. 佛系程序员的月薪五万指南

随机推荐

  1. go语言和python的区别是什么?
  2. golang和go是一样的吗
  3. Golang可以用来做什么
  4. golint的简易使用方法
  5. golang读取文件是否存在
  6. Golang接口哪里好
  7. golang 嵌入乱码怎么办
  8. Golang格式化符号%b是什么意思
  9. Golang反射为什么慢
  10. golang反射用于什么场景