离线包的管理操作包括:预置 H5 应用、利用全局资源包、更新 H5 应用、下载 H5 应用、安装 H5 应用、获取应用信息、校验安全签名以及删除本地应用。
前置条件
预置 H5 应用
通常情况下,第一次打开 H5 应用时,离线包可能未完成下载。此时,需要通过使用 fallback URL 的方式打开应用。
预置 H5 应用相当于在客户端发布的安装包中预先安装可用的 H5 应用。当用户第一次打开预安装应用时,可直接使用离线包资源,提高用户体验。
建议您只预装核心 H5 应用,避免预置了使用率不高的应用。
预置 H5 应用需要完成以下步骤:
从 H5 应用发布后台下载 H5 应用配置的
.json
文件以及需要预置的离线包。将
.json
文件和离线包添加到工程的asset
目录下。在应用启动时,调用预置代码安装应用,示例代码如下:
MPNebula.loadOfflineNebula("h5_json.json", new MPNebulaOfflineInfo("90000000_1.0.0.6.amr", "90000000", "1.0.0.6"));
说明此方法为阻塞调用,请不要在主线程上调用内置离线包方法。
此方法仅能调用一次,若多次调用,仅第一次调用有效。所以需要一次性传入所有需预置的离线包信息。
如果内置多个 amr 包,要确保文件已存在,如不存在,会造成其他内置离线包失败。
利用全局资源包
Nebula 全局资源包解决多个 H5 应用使用同一资源产生的冗余问题。如 React 应用使用 ReactJS 框架代码。您可以将公共资源放入全局资源包,以降低 H5 应用体积。
通常情况下,项目需预置全局资源包,后续更新依然可以通过 H5 应用后台下发。
下方的示例代码指定应用 ID (appId
) 为 66666692
的离线包作为全局资源包使用,并预置 assets/nebulaPreset/66666692
离线包,其中:
getCommonResourceAppList
:用于告知 H5 容器指定 ID 的离线包将作为全局资源包使用。如果您没有配置此 ID,即使内置该离线包,也不会生效。getH5PresetPkg
:用于指定内置全局资源包的路径和版本。H5 容器会从指定的 asset 资源目录加载资源包。不过如果服务端发现更高的版本,该低版本内置包将不会被加载。另外,您也可以使用上文提及的loadOffLineNebula
方法来预置全局资源包,此种情况下,您无需在此方法中配置内置离线包的路径和版本。说明该方法只适用于 H5 全局资源包。
getTinyCommonApp
:仅用于返回小程序的框架资源包 ID,如果您的全局资源包仅被 H5 使用,请不要在此方法中写入该公共资源包 ID。
参考实现类示例代码:
public class H5AppCenterPresetProviderImpl implements H5AppCenterPresetProvider {
private static final String TAG = "H5AppCenterPresetProviderImpl";
// 业务的公共资源包,尽量避开666666开头
private static final String COMMON_BIZ_APP = "xxxxxxxx";
// 小程序专用资源包,业务勿动
private static final String TINY_COMMON_APP = "66666692";
// 预置包的 asset 目录
private final static String NEBULA_APPS_PRE_INSTALL = "nebulaPreset" + File.separator;
// 预置包集合
private static final Map<String, H5PresetInfo> NEBULA_LOCAL_PACKAGE_APP_IDS = new HashMap();
static {
H5PresetInfo h5PresetInfo2 = new H5PresetInfo();
// 内置目录的文件名称
h5PresetInfo2.appId = TINY_COMMON_APP;
h5PresetInfo2.version = "1.0.0.0";
h5PresetInfo2.downloadUrl = "";
NEBULA_LOCAL_PACKAGE_APP_IDS.put(TINY_COMMON_APP, h5PresetInfo2);
}
@Override
public Set<String> getCommonResourceAppList() {
Set<String> appIdList = new HashSet<String>();
appIdList.add(getTinyCommonApp());
appIdList.add(COMMON_BIZ_APP);
return appIdList;
}
@Override
public H5PresetPkg getH5PresetPkg() {
H5PresetPkg h5PresetPkg = new H5PresetPkg();
h5PresetPkg.setPreSetInfo(NEBULA_LOCAL_PACKAGE_APP_IDS);
h5PresetPkg.setPresetPath(NEBULA_APPS_PRE_INSTALL);
return h5PresetPkg;
}
@Override
public Set<String> getEnableDegradeApp() {
return null;
}
@Override
public String getTinyCommonApp() {
return TINY_COMMON_APP;
}
@Override
public InputStream getPresetAppInfo() {
return null;
}
@Override
public InputStream getPresetAppInfoObject() {
return null;
}
}
然后在应用启动时调用:
H5Utils.getH5ProviderManager().setProvider(H5AppCenterPresetProvider.class.getName(), new H5AppCenterPresetProviderImpl());
更新 H5 应用
默认情况下,每次打开 H5 应用,Nebula 都会尝试检查是否有可更新的版本。出于服务端压力考虑,该检查有时间间隔限制,默认为 30 分钟。如果想立即检查最新的可用版本,可以调用下方的代码来请求更新。一般情况下,可以在应用启动或者用户登录后调用。
MPNebula.updateAllApp(new MpaasNebulaUpdateCallback(){
@Override
public void onResult(final boolean success, final boolean isLimit, String detailCode) {
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();
}
});
}
});
下载 H5 应用
MPNebula 提供了手动下载 H5 应用的接口:
/**
* 下载离线包
*
* @param appId 离线包 id
* @param mpaasNebulaDownloadCallback 下载回调
*/
public static void downloadApp(final String appId, final MpaasNebulaDownloadCallback mpaasNebulaDownloadCallback)
安装 H5 应用
MPNebula 提供了手动安装 H5 应用的接口:
/**
* 安装离线包
*
* @param appId 离线包 id
* @param mpaasNebulaInstallCallback 安装回调
*/
public static void installApp(final String appId, final MpaasNebulaInstallCallback mpaasNebulaInstallCallback)
获取应用信息
调用 H5AppProvider 的方法以获取 H5 应用的相关信息:
H5AppProvider provider = H5Utils.getProvider(H5AppProvider.class.getName());
AppInfo appInfo = provider.getAppInfo("10000000"); //获取应用配置
boolean isInstalled = provider.isInstalled("10000000", "1.0.0.0"); //某版本应用是否已经安装
boolean isAvailable = provider.isAvailable("10000000", "1.0.0.0"); //某版本应用离线包是否已经下载完成
校验安全签名
Nebula 具有离线包签名校验机制,以防止恶意程序篡改下载到设备的离线包。通过调用 MPNebula
接口设置验签参数即可开启此机制。如果您使用的基线是 10.1.60 或以上版本,需要额外开启容器配置,详情参见 H5 容器配置。
请在第一次打开离线包前调用
MPNebula
接口,否则将会导致公钥初始化失败。关于公钥与私钥,参见 配置离线包 > 密钥管理。无论客户端是否开启签名校验,在被判断为 root 的手机上都会强制进行签名校验。
/** * @param publicKey 验签公钥 */ public static void enableAppVerification(final String publicKey)
删除本地应用
Nebula 提供了删除本地应用信息的接口。当本地应用信息被删除后,再次打开应用时会重新请求服务端下载更新本地应用信息。
public class MPNebula {
// appId 为离线包或小程序的应用 ID
public static boolean deleteAppInfo(String appId);
}
此 API 支持的最低基线版本分别为 10.1.68.8 和 10.1.60.14。