参考:https://doc.dcloud.net.cn/uni-app-x/plugin/uts-plugin.html
uni-appx开发鸿蒙插件示例
新建步骤拆解
右键点击uni_modules目录 -> 新建插件
创建插件
在HBuilder X 中选中你的项目下uni_modules目录,右键选择新建uni_modules插件, 例如 uts-api
选择类型 uts插件
为了避免和插件市场的其他插件冲突,建议起一个自己的插件前缀名称。
uts插件目录结构
package.json
package.json 为 uni_modules 插件配置清单文件,负责描述插件的基本配置。
上面是一个默认的清单文件示例,关于 package.json 更多描述详见
插件的目录结构
根目录 index.uts 文件是程序主入口。如果插件根目录下没有 index.uts,则会在编译到不同平台时,寻找分平台的目录下的 index.uts 文件。
比如编译到 app-harmony 平台时,如果 uts 插件根目录没有 index.uts,会寻找 utssdk/app-harmony/index.uts。如果也没有找到,会报错。
当同时存在分平台目录的 index.uts 和根目录 index.uts 时,会优先获取具体的分平台目录。
开发者有多种组织自己代码的方式:
- 在插件根目录的 index.uts 中写条件编译代码。简单的业务一个文件搞定
- 在插件根目录 index.uts 中写条件编译,import 分平台的文件
- 不写根目录的 index.uts,直接在分平台目录写 index.uts。不跨端时,比如只做一个 Android 插件,这样写比较简单
插件对外暴露能力的总入口在 interface.uts ,他与 index.uts的关系是声明和实现的关系
App原生配置
鸿蒙原生配置
app-harmony文件夹存放uts插件编译到鸿蒙时的代码逻辑,目前仅支持uts文件。
| 目录名/文件名 | 用途 |
|---|---|
| index.uts | 主入口,interface.uts声明的能力在harmony平台下的实现 |
HBuilderX项目中uts插件目录结构
在 uni-app / uni-app x 的项目工程下,提供了独立的目录 utssdk,来存放 uts 插件。
当然官方更推荐使用 uni_modules 方式,这是更好的包管理方案。
首先确保项目根目录存在 uni_modules 文件夹,如果不存在,需要手动创建一个,目前HB也有创建uni_modules 的指引,还是比较方便的。
编写interface.uts
插件 uts-api 创建完成后,我们需要确定插件对外暴露的 API。
为了多端统一规范的定义对外暴露的接口,获得更好的语法提示和多端一致性约束,标准做法是在 interface.uts 文件中统一定义插件要暴露的 API 类型、 API 的参数类型、返回值类型、错误码类型、错误接口等信息,然后在各端的 index.uts 中做具体的业务实现。
打开 interface.uts 文件,键入下面的源码, 为了方便说明,源码的每个部分的作用都用注释来说明
// 定义 API的参数类型,基本数据类型的参数无需定义,复杂类型参数建议使用自定义type
/**
* myApi 异步函数的参数,在type里定义函数需要的参数以及api成功、失败的相关回调函数。
*/
export type MyApiOptions = {
paramA : boolean
success ?: (res : MyApiResult) => void
fail ?: (res : MyApiFail) => void
complete ?: (res : any) => void
}
// 定义 API 的返回值类型, 基本数据类型的返回值无需特殊定义,复杂类型的参数建议使用自定义type
/**
* 函数返回结果
* 可以是void, 基本数据类型,自定义type, 或者其他类型。
* [可选实现]
*/
export type MyApiResult = {
fieldA : number,
fieldB : boolean,
fieldC : string
}
// 定义 API 对外暴露的错误码,为了更好语法提示和校验效果,建议将错误码用type 定义成联合类型。定义后,使用未指定的错误码将会被警告提示。
// 建议定义的错误码遵循uni错误规范 [详见](https://uniapp.dcloud.net.cn/tutorial/err-spec.html#unierror)。
/**
* 错误码
* 根据uni错误码规范要求,建议错误码以90开头,以下是错误码示例:
* - 9010001 错误信息1
* - 9010002 错误信息2
*/
export type MyApiErrorCode = 9010001 | 9010002;
// 定义 API 的错误回调参数类型,这里定义成 interface 并继承 IUniError 是为了遵循统一的 Uni错误码规范。
// 这里开发者只需要指定 errCode 的类型,以便获得更好的语法提和校验效果。
/**
* myApi 的错误回调参数
*/
export interface MyApiFail extends IUniError {
errCode : MyApiErrorCode
};
// 定义对外暴露的 API 类型,这里是个异步函数
/* 异步函数定义 */
export type MyApi = (options : MyApiOptions) => void
// 定义对外暴露的 API 类型,这里是个同步函数
/* 同步函数定义 */
export type MyApiSync = (paramA : boolean) => MyApiResult
特别注意
interface.uts是官方推荐的多端一致性的最佳实践,不做强制要求,可以根据自己的实际情况决定是否实现。比如某个插件只有一个平台,不写interface也可以。interface.uts文件中定义并export的interface接口例如MyApiFail只能在插件内部的uts文件代码中使用,不能在.uvue文件中使用插件时导入使用。
至此,我们就完成了 interface 的定义,如果你遵循规范,定义了错误码的类型和错误码的 interface 如 MyApiFail, 那么你还需要在 unierror.uts 文件中对 MyApiFail 这个接口做具体实现。
编写unierror.uts
为了获得更好语法提示和校验效果,我们在 interface.uts 文件中已经定义了错误的类型和错误的接口。但是错误码对应的具体错误信息,以及错误对象的具体实现,都还没有完成。 unierror.uts 文件就是专门用来实现这些的。
打开 unierror.uts 文件, 键入下面的源码。同样为了说明,源码的每个部分的作用都用注释来说明。
// 首先导入在 interface.uts 文件中定义的错误码类型,和错误的类型
import { MyApiErrorCode, MyApiFail } from "./interface.uts"
/**
* 定义错误主题,错误主题是Uni错误码的一个标准字段。
* 注意:错误主题一般为插件名称,每个组件不同,需要使用时请更改。
* [可选实现]
*/
export const UniErrorSubject = 'uts-api';
/**
* 错误信息,定义和错误码对应的语义化的提示信息,为了更好的获取,建议定义成Map类型。
* @UniError
* [可选实现]
*/
export const UTSApiUniErrors : Map<MyApiErrorCode, string> = new Map([
/**
* 错误码及对应的错误信息
*/
[9010001, 'custom error mseeage1'],
[9010002, 'custom error mseeage2'],
]);
/**
* 错误对象的具体使用实现,该实现会在 index.uts代码中创建使用。
* 使用时只需要传入特定的错误码即可完成创建。
*/
export class MyApiFailImpl extends UniError implements MyApiFail {
override errCode: MyApiErrorCode
/**
* 错误对象构造函数
*/
constructor(errCode : MyApiErrorCode) {
super();
this.errSubject = UniErrorSubject;
this.errCode = errCode;
this.errMsg = UTSApiUniErrors.get(errCode) ?? "";
}
}
至此我们完成了符合 uni 错误规范的错误码的定义和实现,后面我们就可以去实现插件的具体逻辑了。 Uni错误规范的更多信息详见。
实现接口定义和业务逻辑
分别在插件的 app-android 、app-ios 等目录下打开 index.uts 文件,键入下面的插件源码:
harmonyOS
/**
* 引用鸿蒙系统库,示例如下:
* import deviceInfo from "@ohos.deviceInfo";
* [可选实现,按需引入]
*/
/* 引入 interface.uts 文件中定义的变量 */
import { MyApiOptions, MyApiResult, MyApi, MyApiSync } from '../interface.uts';
/* 引入 unierror.uts 文件中定义的变量 */
import { MyApiFailImpl } from '../unierror';
export {
MyApiOptions
}
/**
* 引入三方库
* 暂不支持,请留意后续更新
*/
/**
* 异步方法
*
* uni-app项目中(vue/nvue)调用示例:
* 1、引入方法声明 import { myApi } from "@/uni_modules/uts-api"
* 2、方法调用
* myApi({
* paramA: false,
* complete: (res) => {
* console.log(res)
* }
* });
*
*/
export const myApi : MyApi = function (options : MyApiOptions) {
if (options.paramA == true) {
// 返回数据
const res : MyApiResult = {
fieldA: 85,
fieldB: true,
fieldC: 'some message'
};
options.success?.(res);
options.complete?.(res);
} else {
// 返回错误
let failResult = new MyApiFailImpl(9010001);
options.fail?.(failResult)
options.complete?.(failResult)
}
}
/**
* 同步方法
*
* uni-app项目中(vue/nvue)调用示例:
* 1、引入方法声明 import { myApiSync } from "@/uni_modules/uts-api"
* 2、方法调用
* myApiSync(true);
*
*/
export const myApiSync : MyApiSync = function (paramA : boolean) : MyApiResult {
// 返回数据,根据插件功能获取实际的返回值
const res : MyApiResult = {
fieldA: 85,
fieldB: paramA,
fieldC: 'some message'
};
return res;
}
使用插件
下面的示例代码为uni-app-x代码
上面的代码,我们完成了一个名为 “uts-api” 的UTS 插件,在 uvue 文件中使用该插件的代码示例如下:
// 导入要使用的插件
import { myApi, myApiSync, MyApiOptions } from "@/uni_modules/uts-api";
methods: {
testMyApi() {
// 调用异步方法示例
let options = {
paramA: false,
complete: (res : any) => {
console.log(res)
}
} as MyApiOptions;
myApi(options);
},
testMyApiSync() {
// 调用同步方法示例
console.log(myApiSync(true))
},
}
运行和编译uts插件,需要在HBuilderX的设置中配置Android和iOS的环境,见如下文档:
开发uts插件,调试、打断点是重要帮手,参考如下文档
获取电量插件示例
以获取电量为例,介绍uts插件开发步骤
首先在 uni_modules 目录下新建名为 uts-getbatteryinfo 的 uts 插件
在鸿蒙平台目录下,编辑index.uts,键入以下内容。
// index.uts
// 引用android api
import Context from "android.content.Context";
import BatteryManager from "android.os.BatteryManager";
import { UTSAndroid } from "io.dcloud.uts";
export function getBatteryCapacity(): string {
// 获取android系统 application上下文
const context = UTSAndroid.getAppContext();
if (context != null) {
const manager = context.getSystemService(
Context.BATTERY_SERVICE
) as BatteryManager;
const currentLevel: number = manager.getIntProperty(
BatteryManager.BATTERY_PROPERTY_CAPACITY
);
return '' + currentLevel + '%';
}
return "0%";
}
至此,我们已经完成一个Android平台上获取电量的原生能力封装。
我们可以在vue页面中这样使用它:
import { getBatteryCapacity } from "@/uni_modules/uts-getbatteryinfo";
console.log(getBatteryCapacity())
有些场景下,我们期望 将获取电量的能力封装为 异步的接口,我们可以使用下面的代码
import Context from "android.content.Context";
import BatteryManager from "android.os.BatteryManager";
import { UTSAndroid } from "io.dcloud.uts";
type GetBatteryInfoOptions = {
success?: (res: object) => void
fail?: (res: object) => void
complete?: (res: object) => void
}
export function getBatteryInfo(options: GetBatteryInfoOptions) {
const context = UTSAndroid.getAppContext();
if (context != null) {
const manager = context.getSystemService(
Context.BATTERY_SERVICE
) as BatteryManager;
const level = manager.getIntProperty(
BatteryManager.BATTERY_PROPERTY_CAPACITY
);
const res = {
errCode: 0,
errSubject: "uts-getbatteryinfo",
errMsg: "getBatteryInfo:ok",
level,
isCharging: manager.isCharging()
}
options.success?.(res)
options.complete?.(res)
} else {
const res = {
errCode: 1001,
errSubject: "uts-getbatteryinfo",
errMsg: 'getBatteryInfo:fail getAppContext is null'
}
options.fail?.(res)
options.complete?.(res)
}
}
对应的使用代码需要调整为:
import {getBatteryInfo} from "@/uni_modules/uts-getbatteryinfo";
getBatteryInfo({
success(res) {
uni.showToast({
title: "当前电量:" + res.level + '%',
icon: 'none'
});
}
})
harmonyOS平台
在utssdk目录下创建harmonyOS平台目录app-harmony
在harmonyOS平台目录下,编辑index.uts,键入以下内容,即可完成harmonyOS平台获取电量能力
import batteryInfo from '@ohos.batteryInfo';
import { GetBatteryInfo, GetBatteryInfoOptions, GetBatteryInfoSuccess, GetBatteryInfoResult, GetBatteryInfoSync } from '../interface.uts';
export const getBatteryInfoSync : GetBatteryInfoSync = function () : GetBatteryInfoResult {
return {
level: batteryInfo.batterySOC,
isCharging: batteryInfo.chargingStatus === batteryInfo.BatteryChargeState.ENABLE || batteryInfo.chargingStatus === batteryInfo.BatteryChargeState.FULL,
};
}
export const getBatteryInfo : GetBatteryInfo = function (options : GetBatteryInfoOptions) {
const batteryInfoResult : GetBatteryInfoSuccess = {
errMsg: "getBatteryInfo:ok",
level: batteryInfo.batterySOC,
isCharging: batteryInfo.chargingStatus === batteryInfo.BatteryChargeState.ENABLE || batteryInfo.chargingStatus === batteryInfo.BatteryChargeState.FULL,
}
try {
options.success && options.success(batteryInfoResult)
} catch (e) {
console.error(e)
}
try {
options.complete && options.complete(batteryInfoResult)
} catch (e) {
console.error(e)
}
}
以上就是整个的uni-appx开发鸿蒙插件示例,希望可以帮到大家。
1560

被折叠的 条评论
为什么被折叠?



