技术干货 | mPaaS 小程序高玩带你起飞:客户端预置小程序无视网络质量
传统的小程序技术容易受到网络环境影响,当网络质量不佳时可能导致拉取不到小程序包的情况。通过预置小程序,即可规避该问题。本文介绍了预置小程序的原理和预置小程序的实现过程。
什么是预置小程序
预置小程序是指将小程序的渲染、逻辑、配置等静态资源打包在一个压缩包内,客户端预先下载小程序包到本地、直接从本地加载资源的过程。预置小程序可以最大程度地摆脱网络环境对 mPaaS 小程序页面的影响。使用预置包能够为客户端带来以下优势:
- 提升用户体验
通过预置包的方式把页面内静态资源嵌入到应用中并随应用一起发布,可以使用户第一次开启应用时即无需依赖网络环境下载资源,可以直接开始使用。 - 实现动态更新
在推出新版本或紧急发布的时候,可以在小程序 IDE 中进行迭代开发,通过 mPaaS 控制台发布,客户端中集成的小程序 SDK 会自动将小程序更新到最新的版本。这种发布无需通过应用商店审核,可以让用户及早接收到更新。
预置小程序的实现原理
本文从以下方面介绍了预置小程序的实现原理:
- 小程序预置包的结构
- 小程序预置包的使用过程
小程序预置包的结构
小程序预置包是一个 .amr
格式的压缩文件,将后缀 amr
改成 zip
解压缩后,可以看到其中包含的 HTML 资源和 JavaScript 代码等。待小程序容器加载后,这些资源和代码能在 UC 内核渲染。
以 Android 系统为例,下图显示了一般资源包的目录结构:
- 一级目录:一般为资源包的 ID,如 2020121620201216_1.0.1.0.zip。
- 二级目录及往后即为业务自定义的资源文件。并设定当前预置包默认打开的主入口文件,如
/index.html
。
小程序预置包的使用过程
使用小程序预置包的过程可以分为以下三个步骤:
- 请求包信息
从服务端请求小程序包,并将小程序包信息存储到本地数据库的过程。包信息包含了小程序包的下载地址、小程序包版本号等。 - 下载小程序包
把小程序包从服务端下载到手机。 - 安装小程序包
下载目录,拷贝到手机安装目录。
前提条件
- 已接入小程序组件。更多关于小程序组件的接入信息,请参见 快速开始使用小程序。
- 已接入 H5 容器 组件。更多关于 H5 容器的接入信息,请参见 快速开始使用 H5 容器。
操作步骤-Android
- 预置小程序包。
-
- 在 mPaaS 控制台发布小程序包并下载 AMR 文件和配置文件。
- 将下载到的 AMR 文件和配置文件放置在 mPaaS 项目的 assets 目录下。
- 在工程中添加预置代码,以在应用启动时调用预置代码安装应用。预置代码示例如下:
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 包,需要要确保文件已存在;如不存在,会造成其他内置预置包失败。
- 启动小程序。启动小程序的示例代码如下。
/** * 启动小程序 * * @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
- 预置小程序包。
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 -
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
缓存你问题真不少!
引言 2021年,2月底,一个超级疲惫的下午,离下班还有30分钟,小航拿了一袋每日坚果,对我说:”温哥,来来来,吃个坚果,开心下” 有了前几次的,经验,我意识到,这兄弟又要问题问题,委婉的回绝到:”谢谢好意,你吃吧,我不饿”。 小航,一看我有所防备,有拿出了安慕希,并且抓住了我的手臂,说道:“大神,我有困惑,请您帮帮我” 看他如此诚恳,我不好意思的说道:“大神不敢当,水平有限,恐无法为你解惑”。 小航一看有戏,有给了我一袋每日坚果,眼中有光的说道:“哥,您指点一二,无论对错,我都愿意听” 我感动(dong xi hao chi)的说:“什么问题,我试试看” 小航立刻说道:“使用缓存都有什么问题” 我缓缓道来:“主要四个问题,击穿,穿透,雪崩,污染” 问题描述 逐个解决 缓存击穿 热点key过期了,请求打到了数据库 解决方式 不给热点key设置过期时间 缓存穿透 缓存没有,数据库也没有。 解决方式 缓存空值或缓存缺省值 对入参进行校验,屏蔽无效参数请求 在redis前置布隆过滤器,快速判断 缓存雪崩 大量key同时失效 给key的过期时间加上随机数,避免同时过期 Redis挂了 Redi...
- 下一篇
Electron 窗口卡顿问题的处理
最近发现使用 Electron 做跨平台桌面软件开发是一种很有意思的体验:只要你熟悉最基础的前端知识,在配合 Electron Document 就可以开发跨平台的桌面软件,想想还是很香的。 Electron 在其 官方 demo 中提供了常见桌面软件大部分基础性事件处理模式,包括:BrowserWindow 的创建及切换、系统菜单管理、main process 以及 renderer process 之间的通信、系统托盘处理、消息通知体系等。如果想要快速了解并掌握 Electron 开发的话,相信这应该是最好的教材。 然而,在官方提供的 demo 中有两段个人认为处理的并不是特别好的代码。首先是创建窗口时对 close 事件的响应: function createWindow() { mainWindow = new BrowserWindow(windowOptions) //..... mainWindow.on('closed', () => { mainWindow = null }) } 按照 Electron 提供的文档中对 close 的说明:close 事件 会...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Hadoop3单机部署,实现最简伪集群
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7,CentOS8安装Elasticsearch6.8.6