前言:鸿蒙运行uiapp小程序来源于uiapp的SDK包提供的能力,如有更多定制化业务,请自行查看SDK内容导入相应的API,比方以下
- import {
- openUniMP,
- releaseWgtToRunPath,
- getUniMPRunPath,
- isExistsUniMP,
- getAppVersionInfo,
- registerModule
- } from '@dcloudio/uni-app-runtime'
复制代码 告示:只支持Vue3版本运行
uniMP小程序
#初始化 sdk 全局环境
- interface IInitConfig {
- debug?: boolean
- }
- function init(ability: UIAbility, stage: window.WindowStage, config?: IInitConfig)
复制代码 复制代码
#获取uni小程序应用资源部署路径
- function getUniMPRunPath(appID: string): string
复制代码 复制代码
#判断应用资源是否已经部署
- function isExistsUniMP(appId: string): boolean
复制代码 复制代码
#将wgt应用资源包部署到运行路径中
- type ReleaseWgtToRunPathCallback = (code: 1 | -1, error?: Error) => void
- function releaseWgtToRunPath(appID: string, wgtPath: string, callback: ReleaseWgtToRunPathCallback)
复制代码 复制代码
#获取已经部署的小程序应用资源版本信息
- interface IAppVersionInfo {
- name: string
- code: string
- }
- function getAppVersionInfo(appId: string): IAppVersionInfo | null
复制代码 复制代码
#启动小程序应用并获得IUniMP实例
- interface ICapsuleStyle {
- backgroundColor?: string
- textColor?: string
- highlightColor?: string
- borderColor?: string
- }
- interface ICapsuleMenuActionSheetItem {
- id: string
- title: string
- }
- interface IOpenUniMPConfig {
- showCapsuleButton?: boolean
- capsuleMenuActionSheetItems?: ICapsuleMenuActionSheetItem[]
- capsuleButtonStyle?: ICapsuleStyle
- redirectPath?: string
- extraData?: Object // 传递给小程序的额外数据,小程序中onLaunch,uni.getLaunchOptionsSync可以获取
- }
- export interface IUniMP {
- hide(): void
- show(): void
- close(): void
- sendUniMPEvent: (event: string, data: ESObject) => void
- on(event: 'uniMPEvent', callback: (event: string, data: ESObject, notify: (...args: ESObject[]) => void) => void): void
- on(event: 'menuItemClick', callback: (id: string) => void): void
- on(event: 'close' | 'show' | 'hide', callback: () => void): void
- off(name: string, callback: Function): void
- }
- function openUniMP(appID: string, config?: IOpenUniMPConfig): IUniMP
复制代码 复制代码
#IUniMP实例下的API
#隐藏当前小程序应用
复制代码
#表现当前小程序应用
复制代码
#关闭当前小程序应用
复制代码
#向小程序发送变乱
- sendUniMPEvent: (event: string, data: ESObject) => void
复制代码 复制代码
#监听小程序发送过来的变乱
- on(event: 'uniMPEvent', callback: (event: string, data: ESObject, notify: (...args: ESObject[]) => void) => void): void
复制代码 复制代码
#监听右上角菜单的点击变乱
- on(event: 'menuItemClick', callback: (id: string) => void): void
复制代码 复制代码
#监听小程序隐藏、表现、关闭变乱
- on(event: 'close' | 'show' | 'hide', callback: () => void): void
复制代码 复制代码
#移除对应的监听变乱
- off(name: string, callback: Function): void
复制代码
- 修改鸿蒙项目根目次文件 oh-package.json5 的依赖 "@dcloudio/uni-app-runtime": "版本号",如下图所示 查看最新版本号
- 点击右上角 Sync Now,并等候 Sync 结束
- 首先需要初始化uiapp SDK包 ,初始化如下
- 在EntryAbility文件入口如下
- import { init } from '@dcloudio/uni-app-runtime'
复制代码- init(this, windowStage, {
- debug: true
- })
复制代码- <img alt="" src="https://i-blog.csdnimg.cn/direct/1eb1fece6be84fdf85cbfa2791a61251.png" />
复制代码 - 将生成的wgt包拷贝到 entry/src/main/resources/resfile 目次下,如下图所示
4.再通过 releaseWgtToRunPath 函数释放 wgt 包到运行目次,最后通过 openUniMP 函数打开小程序,代码如下
在线拉取运行:
- /**
- * 下载 uiapp 包
- */
- function downloadUiApp(fileName: string, downUrl: string, md5Code: string): Promise<string> {
- return new Promise((resolve) => {
- DownloadUiApp.downloadUiApp(
- downUrl,
- fileName,
- md5Code,
- {
- onError: (code: string = '') => {
- // 下载错误
- if (code === 'MD5_error') {
- promptAction.showToast({
- message: '文件损坏,请重新点击应用'
- })
- }
- resolve(code)
- },
- onSuccess: (srcFilePath: string) => {
- // 下载并保存成功
- Logger.info('下载文件完成 地址为', srcFilePath)
- resolve(srcFilePath)
- }
- })
- })
- }
复制代码 下载文件Class
- import { common } from '@kit.AbilityKit';
- import fs, { ReadOptions, WriteOptions } from '@ohos.file.fs';
- import { BusinessError, request } from '@kit.BasicServicesKit';
- import { fileIo } from '@kit.CoreFileKit';
- import Logger from './Logger'
- import { cryptoFramework } from '@kit.CryptoArchitectureKit';
- Logger.prefix = 'uiapp'
- export class DownloadUiApp {
- /**
- * 获取应用沙箱存储目录 统一一下,方便APP设置页面删除
- * @returns
- */
- static getLocalCacheDir(): string {
- let cache_dir_name = "uiapps";
- let cache_dir = getContext().filesDir + "/" + cache_dir_name;
- console.info(`createCacheDir cache_dir: ${cache_dir}`);
- let existAppCacheDir = fileIo.accessSync(cache_dir, fileIo.AccessModeType.EXIST)
- if (!existAppCacheDir) {
- fileIo.mkdirSync(cache_dir, true);
- }
- return cache_dir
- }
- static async checkAndRemoveFile(path: string) {
- const exist = await fs.access(path);
- if (exist) {
- await fs.unlink(path);
- }
- }
- //计算文件的MD5码
- public static computeMD5(file: string | number): Uint8Array {
- let md5Stream: fs.Stream
- if (typeof file === 'string') {
- md5Stream = fs.createStreamSync(file, "r");
- } else {
- md5Stream = fs.fdopenStreamSync(file, "r")
- }
- let dataBuff: ArrayBuffer = new ArrayBuffer(4096)
- let mdAlgName = "MD5";
- let md = cryptoFramework.createMd(mdAlgName);
- let readCount = md5Stream.readSync(dataBuff)
- while (readCount > 0) {
- let messageData = new Uint8Array(dataBuff.slice(0, readCount));
- let updateMessageBlob: cryptoFramework.DataBlob = { data: messageData };
- md.updateSync(updateMessageBlob);
- readCount = md5Stream.readSync(dataBuff)
- }
- let mdResult = md.digestSync();
- md5Stream.closeSync()
- return mdResult.data
- }
- public static uint8ArrayToHexStr(data: Uint8Array): string {
- let hexString = '';
- let i: number;
- for (i = 0; i < data.length; i++) {
- let char = ('00' + data[i].toString(16)).slice(-2);
- hexString += char;
- }
- return hexString;
- }
- public static checkFileMD5(srcFilePath: string, fileMd5Code: string) {
- let file = fs.openSync(srcFilePath, fs.OpenMode.READ_ONLY)
- // 校验文件完整性
- let md5Code = DownloadUiApp.uint8ArrayToHexStr(DownloadUiApp.computeMD5(file.fd)).toUpperCase()
- Logger.info('md5Code:' + md5Code)
- return md5Code === fileMd5Code
- }
- public static async downloadUiApp(
- downUrl: string,
- fileName: string,
- fileMd5Code: string,
- callback: DownloadCallback
- ) {
- if (!downUrl.startsWith("http://") && !downUrl.startsWith("https://")) {
- callback.onError()
- Logger.info('uiapp 请传入正确的请求URL!')
- return
- }
- try {
- // 获取应用文件路径
- const localCacheDir = DownloadUiApp.getLocalCacheDir();
- let srcFilePath = `${localCacheDir}/${fileName}`
- await DownloadUiApp.checkAndRemoveFile(srcFilePath);
- let context = getContext() as common.UIAbilityContext;
- request.downloadFile(context, {
- url: downUrl,
- filePath: srcFilePath,
- background: false,
- enableMetered: true,
- enableRoaming: true
- })
- .then((downloadTask: request.DownloadTask) => {
- downloadTask.on('complete', () => {
- let isComplete = DownloadUiApp.checkFileMD5(srcFilePath, fileMd5Code)
- if (isComplete) {
- Logger.info('uiapp 下载uiapp 成功!')
- callback.onSuccess(srcFilePath)
- } else {
- fs.unlinkSync(srcFilePath)
- callback.onError('MD5_error')
- }
- })
- downloadTask.on('fail', () => {
- Logger.info('uiapp 下载uiapp失败')
- callback.onError('down_fail')
- });
- }).catch((err: BusinessError) => {
- Logger.info('uiapp 下载uiapp异常')
- callback.onError('down_error')
- });
- } catch (error) {
- let err: BusinessError = error as BusinessError;
- Logger.info('uiapp 打开下载过程失败')
- callback.onError('down_open_error')
- }
- }
- }
- /**
- * 下载文件的返回结果
- */
- interface DownloadCallback {
- // MD5_error MD5校验失败
- onError: (code?: string) => void;
- onStart?: () => void;
- inProgress?: (progress: number, total: number) => void;
- onSuccess: (srcFilePath: string) => void;
- }
- 运行在线拉取的uiapp包
复制代码
- /**
- * 更新 uiapp 版本信息
- */
- function updateUiAppFile(appId: string, newSrcFilePath: string) {
- let oldSrcFilePath = preferenceUtil.getPreference(appId, '') as string
- if (oldSrcFilePath && fs.accessSync(oldSrcFilePath)) {
- fs.unlinkSync(oldSrcFilePath)
- Logger.info('删除 uiapp 老版本地址' + oldSrcFilePath)
- }
- if (oldSrcFilePath !== newSrcFilePath) {
- preferenceUtil.putPreference(appId, newSrcFilePath)
- Logger.info('更新 uiapp 新版本地址' + newSrcFilePath)
- }
- }
- function readLocalUiAppToSandbox(appId: string): Promise<string> {
- return new Promise(async (resolve) => {
- try {
- Logger.info(`读取本地文件 ${appId}.wgt`)
- let context = getContext() as common.UIAbilityContext;
- let val: Uint8Array = context.resourceManager.getRawFileContentSync(`${appId}.wgt`);
- let localCacheDir: string = DownloadUiApp.getLocalCacheDir()
- //目录不存在,则先创建存放小程序目录
- if (!fs.accessSync(localCacheDir, fs.AccessModeType.EXIST)) {
- await fs.mkdir(localCacheDir, true)
- }
- Logger.info("小程序 pathDir: " + localCacheDir);
- // 待拷贝文件沙箱路径
- let filePath: string = `${localCacheDir}/${appId}.wgt`;
- // 若文件不存在,则创建文件。
- let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
- let writeLen = fs.writeSync(file.fd, val.buffer as ArrayBuffer);
- fs.closeSync(file);
- Logger.info('复制到沙箱路径', filePath)
- resolve(filePath)
- } catch (error) {
- Logger.info('读取本地文件错误')
- resolve('')
- }
- })
- }
- // 小程序运行实例集合
- let uniMPInstanceCollections: Record<string, ESObject> = {}
- function uniMenuItemsClick(code: string, uniMPInstance: ESObject) {
- Logger.info('menuItemClick::' + code)
- switch (code) {
- case CommonConstants.UNI_BACKEND_CODE:
- uniMPInstance.hide()
- break;
- case CommonConstants.UNI_CLOSE_CODE:
- // 关闭小程序
- uniMPInstance.close()
- uniMPInstance = null
- break;
- }
- }
- /**
- * 调起 uiapp
- */
- async function loadUiApp(appId: string, redirectPath?: string) {
- //进度加载类弹出框
- const dialogId = DialogHelper.showLoadingDialog({
- loadType: SpinType.spinP,
- loadColor: Color.White,
- loadSize: 30,
- backgroundColor: '#BB000000',
- content: "加载中…",
- fontSize: 15,
- autoCancel: true
- })
- try {
- let uiappInfo = await checkUiAppStatus(appId)
- let uiAppDirPath = uiappInfo.uiAppDirPath
- if (uiappInfo.code === 'version_error' || true) {
- let localCacheDir: string = DownloadUiApp.getLocalCacheDir()
- let srcFilePath = `${localCacheDir}/${appId}`
- if (!fs.accessSync(srcFilePath)) {
- let sandboxFilePath = await readLocalUiAppToSandbox(appId)
- if (sandboxFilePath) {
- uiAppDirPath = sandboxFilePath
- } else {
- promptAction.showToast({
- message: '获取版本信息异常'
- })
- Logger.info('version_error return')
- return
- }
- }
- }
- Logger.info(`完成检查动作 获得地址 :: ${JSON.stringify(uiappInfo)}`)
- DialogHelper.closeDialog(dialogId)
- // 已经存在,并且运行中直接打开小程序
- if (uniMPInstanceCollections[appId] && uniMPInstanceCollections[appId].isRunning()) {
- Logger.info('小程序 uniMPInstance: show')
- uniMPInstanceCollections[appId].show()
- } else {
- // 小程序没执行或者已经被关闭掉了的重新运行
- releaseWgtToRunPath(appId, uiAppDirPath, (code) => {
- Logger.info('小程序:: getAppVersionInfo' + JSON.stringify(getAppVersionInfo(appId)))
- if (code === CommonConstants.UIAPP_RUN_SUCCESS) {
- updateUiAppFile(appId, uiAppDirPath)
- uniMPInstanceCollections[appId] = openUniMP(appId, {
- redirectPath: redirectPath || '',
- capsuleMenuActionSheetItems: [
- {
- id: CommonConstants.UNI_BACKEND_CODE,
- title: '将小程序隐藏到后台'
- },
- {
- id: CommonConstants.UNI_CLOSE_CODE,
- title: '关闭小程序'
- }
- ]
- });
- uniMPInstanceCollections[appId].capsuleCloseButtonClick = () => {
- uniMenuItemsClick(CommonConstants.UNI_CLOSE_CODE, uniMPInstanceCollections[appId])
- }
- uniMPInstanceCollections[appId].on('menuItemClick', (id: string) => {
- uniMenuItemsClick(id, uniMPInstanceCollections[appId])
- })
- }
- })
- }
-
- } catch (error) {
- DialogHelper.closeDialog(dialogId)
- let code = (error as BusinessError).code;
- let message = (error as BusinessError).message;
- Logger.info(`执行打开小程序失败 code: ${code} message: ${message}`)
- }
- }
复制代码 注册模块提供给uiapp小程序使用
- /**
- * 注册 BGYUniCommonNativeModule 模块,供uiapp小程序调用
- */
- registerModule('BGYUniCommonNativeModule', {
- getUserInfo(data: object, callback: Function) {
- let userInfoData = preferenceUtil.getPreference('userInfoData', '') as string
- Logger.info('小程序 getUserInfo' + userInfoData)
- callback && callback({
- code: 200,
- data: JSONUtil.isJSONStr(userInfoData) && JSONUtil.jsonToBean(userInfoData) || null
- })
- }
- })
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
|