前提
uniapp已经支持安卓、iOS、鸿蒙,但是到目前发稿前,uniapp对鸿蒙的支持还是存在不少问题,例如在HBuilderX里选择发行
>AppHarmony-本地打包
时,编译过程中,会有报错。我的做法就是不用发行的方式编译打包,改用运行
>运行到手机或模拟器
>运行到鸿蒙
(前提是需要有个鸿蒙5.0以上的手机)。
另外有个更重要的问题,就是uniapp目前对鸿蒙APP热更新支持存在问题,可以在到论坛搜索相关问题。我也提了相关bug及解决方案,但官方没有回应。
看到网友的提问,还是不清楚怎么处理,便在这里把我的操作流程说一下,目前我们公司按照这个流程操作,不会出现第一次热更新成功,第二次失败,每次都是成功的。
另外有一点很重要,就是安卓和iOS的热更新包 与 鸿蒙的热更新包 要分开使用。即安卓和iOS的只能使用安卓和iOS的热更新包,鸿蒙5.0以上的系统只能使用鸿蒙的热更新包。
鸿蒙APP热更新支持操作流程
按照uniapp官方调用鸿蒙原生API文档添加后文提供的代码,安卓和iOS相关的用不到,如果编译异常,空实现即可
先删除旧的 HBuilderX 编译出鸿蒙工程,再通过 HBuilderX 编译出新的鸿蒙工程
关闭 HBuilderX 运行的鸿蒙
到编译出来新鸿蒙工程里(刚刚通过HBuilderX 编译出新的鸿蒙工程),将 entry/src/main/ets/entryability/EntryAbility.ets
文件里的 HBuilder
替换为 uniapp工程的mainfest.json
里appid
的值(即构造函数中,调用super
方法的第一个参数替换为你的appid)
将 entry/src/main/resources/resfile/apps/HBuilder
复制一份处理到 entry/src/main/resources/resfile/apps
目前下,且文件夹名为 uniapp工程的mainfest.json
里appid
的值
使用DevEco-Studio编译打包
代码部分
鸿蒙热更新使用,这部分添加到uniapp的工程里需要热更新的地方,注意与安卓、iOS的热更新分开
if(){
/**
* 判断是原生鸿蒙系统后进入这里热更新处理
* 需要注意,原生鸿蒙系统要先申请网络权限和存储权限
*/
let appid = 'uni-app应用标识(AppID),查看uniapp工程的manifest.json文件'
let url = 'wgt热更新包下载链接'
let filename = 'wgt热更新包本地存储名称'
let progressFun = function(res){
const progress = parseInt(res.receivedSize / res.totalSize * 100);
// 显示下载进度
}
uni.myFileDownload({
url: url,
name: filename,
progress : progressFun,
complete : (res) =>{
if(res.err == 0){
// 下载完成 准备安装
...
// 安装
uni.myInstall(appid, res.filePath, (res2)=>{
// 安装结束
...
// 安装成功重启
res2 && uni.myRestartApp()
})
}
}
})
}
package.json
文件内容
...其他属性
"uni-ext-api": {
"uni": {
"myFileDownload": {
"name": "myFileDownload",
"app": {
"js": false,
"kotlin": false,
"swift": false,
"arkts": true
}
},
"myInstall": {
"name": "myInstall",
"app": {
"js": false,
"kotlin": false,
"swift": false,
"arkts": true
}
},
"myRestartApp": {
"name": "myRestartApp",
"app": {
"js": false,
"kotlin": false,
"swift": false,
"arkts": true
}
}
}
},
...其他属性
/utssdk/interface.uts
文件内容
export interface Uni {
/**
* 下载热更新包
* @param {FileDownloadOptions} options 下载参数
*/
myFileDownload(options : FileDownloadOptions) : void;
/**
* 安装热更新包
* @param {string} appid uni-app应用标识(AppID),查看uniapp工程的manifest.json文件
* @param {string} path wgt下载路径
* @param {null|Callback} callback 回调
*/
myInstall(appid: string, path: string, callback : null|Callback) : void;
/**
* 重启app
*/
myRestartApp() : void;
}
// 下载完成结果
export type FileDownloadCallbackResult = {
url: string,
name: string,
filePath: null|string,
/**
* 错误码 0表示没有错误
*/
err: number,
/**
* 错误信息
*/
errMsg : null|string
};
// 下载进度信息
export type FileDownloadProgress = {
receivedSize: number,
totalSize: number
};
// 下载进度回调
export type FileDownloadProgressCallback = (callbackResult : FileDownloadProgress) => void;
// 下载完成回调
export type FileDownloadCallback = (callbackResult : FileDownloadCallbackResult) => void;
export type FileDownloadOptions = {
url: string,
name: string,
progress : null|FileDownloadProgressCallback,
complete : FileDownloadCallback
};
export type MyFileDownload = (options : FileDownloadOptions) => void;
export type Callback = (callbackResult : boolean) => void;
export type MyInstall = (appid: string, path: string, callback : null|Callback) => void;
export type MyRestartApp = () => void;
/utssdk/app-harmony/index.uts
文件内容
import {
FileDownloadOptions,
FileDownloadProgress,
FileDownloadCallbackResult,
MyFileDownload,
Callback,
MyInstall,
MyRestartApp
} from '../interface.uts';
import {
common as myAppcommon, Want } from '@kit.AbilityKit';
import {
request as myAppRequest } from '@kit.BasicServicesKit';
import {
fileIo } from '@kit.CoreFileKit';
// 热更新的核心方法
import {
releaseWgtToRunPath } from '@dcloudio/uni-app-runtime';
export const myFileDownload: MyFileDownload = function(options : FileDownloadOptions) : void {
let context = getContext() as myAppcommon.UIAbilityContext;
let filesDir = context.filesDir
let filePath = filesDir + '/' + options.name
try {
// 删除文件
fileIo.unlinkSync(filePath)
} catch (error) {
}
try {
let config: myAppRequest.DownloadConfig = {
url: options.url,
filePath: filePath
}
myAppRequest.downloadFile(context, config).then((downloadTask: myAppRequest.DownloadTask) => {
if(options.progress){
let progressCallback = (receivedSize: number, totalSize: number) => {
let progressInfo : FileDownloadProgress = {
receivedSize: receivedSize,
totalSize: totalSize
}
options.progress?.(progressInfo)
}
downloadTask.on('progress', progressCallback);
}
let failCallback = (err: number) => {
let errMsg = 'Failed to download the task('+options.url+'). Code: '+err
let fileDownloadCallbackResult : FileDownloadCallbackResult = {
url: options.url,
name: options.name,
filePath: null,
err: 1,
errMsg : errMsg
}
options.complete(fileDownloadCallbackResult)
}
let completeCallback = () => {
let fileDownloadCallbackResult : FileDownloadCallbackResult = {
url: options.url,
name: options.name,
filePath: filePath,
err: 0,
errMsg : 'ok'
}
options.complete(fileDownloadCallbackResult)
}
downloadTask.on('fail', failCallback)
downloadTask.on('complete', completeCallback)
}).catch(err => {
});
} catch (error) {
}
}
export const myInstall: MyInstall = function(appid: string, path: string, callback : null|Callback) : void{
try{
releaseWgtToRunPath(appid, path, (code: 1 | -1, error?: Error)=>{
callback?.(code == 1)
})
}catch(err){
callback?.(false)
}
}
export const myRestartApp: MyRestartApp = function() : void {
try {
const context = getContext() as myAppcommon.UIAbilityContext
let applicationContext = context.getApplicationContext();
let want: Want = {
bundleName: context.abilityInfo.bundleName,
abilityName: 'EntryAbility'
};
applicationContext.restartApp(want);
} catch (error) {
}
}
编译出来新鸿蒙工程里entry/src/main/ets/entryability/EntryAbility.ets
文件内容
import {
UniEntryAbility } from "@dcloudio/uni-app-runtime";
import {
initUniModules } from "../uni_modules/index.generated";
import BuildProfile from "BuildProfile";
const appid = 'uni-app应用标识(AppID),查看uniapp工程的manifest.json文件'
initUniModules();
interface IHmr {
init: Function
}
export default class EntryAbility extends UniEntryAbility {
constructor() {
super(appid, {
debug: BuildProfile.DEBUG,
});
if (BuildProfile.DEBUG) {
import('@uni_modules/hmr-for-uni-app').then((hmr: IHmr) => {
hmr.init()
}).catch((err: Error) => {
console.error('[HMR] import @uni_modules/hmr-for-uni-app failed: ' + err.message)
})
}
}
}
暂无评论内容