Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
unidocs-uni-app-x-zh
提交
42588701
U
unidocs-uni-app-x-zh
项目概览
DCloud
/
unidocs-uni-app-x-zh
通知
144
Star
2
Fork
33
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
9
列表
看板
标记
里程碑
合并请求
11
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
unidocs-uni-app-x-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
9
Issue
9
列表
看板
标记
里程碑
合并请求
11
合并请求
11
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
42588701
编写于
8月 02, 2024
作者:
杜庆泉
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
更新uts插件混编文档
上级
3a9b9b59
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
177 addition
and
39 deletion
+177
-39
docs/plugin/uts-plugin-hybrid.md
docs/plugin/uts-plugin-hybrid.md
+177
-39
未找到文件。
docs/plugin/uts-plugin-hybrid.md
浏览文件 @
42588701
# UTS原生混编介绍
`HBuilder X 4.25`
起,UTS插件可以直接使用原生的kotlin、java、swift代码,即
`UTS原生混编`
`HBuilder X 4.25`
起,UTS插件可以直接使用原生的kotlin、java、swift代码,即
`UTS原生混编`
(下文简称:
`原生混编`
)
## `UTS原生混编`的优势和适用场景
之前,开发者只能使用
[
UTS语言
](
https://doc.dcloud.net.cn/uni-app-x/uts/
)
来开发
[
UTS插件
](
https://doc.dcloud.net.cn/uni-app-x/plugin/uts-plugin.html
)
。
对于不熟悉原生开发的插件作者来说,往往需要下面的步骤来实现原生API功能的封装:
## 原生混编的优势和适用场景
+
1 通过搜索引擎/AIGC/原生API文档 得到一段自己想要的功能对应原生代码(kotlin/swift等)
`原生混编`
出现之前,开发者只能使用
[
UTS语言
](
https://doc.dcloud.net.cn/uni-app-x/uts/
)
来开发
[
UTS插件
](
https://doc.dcloud.net.cn/uni-app-x/plugin/uts-plugin.html
)
。
+
2 手动翻译这段代码为UTS
对于不熟悉原生的开发者来说,要实现原生功能的开发,往往要经过下面的步骤:
+
3 如果存在UTS不支持的语法,还需要把原生代码封装成 aar/framework 等原生库形式,再供UTS代码调用
1 通过`搜索引擎`/`AIGC`/`原生API`文档 得到对应功能的关键原生代码(kotlin/swift等)
2 手动翻译这段代码为`UTS`
这是一件很繁琐的事情,
`UTS原生混编`
的出现彻底解决了这个问题:
3 如果存在`UTS`不支持的语法,还需要把原生代码封装成 `aar`/`framework` 等原生库形式,再供`UTS`代码调用
开发者只需要把原生环境中可用的 kotlin/swift/java 等原生代码按照约定放在UTS插件中,就可以通过
`uts`
文件就可以无缝的使用。
在UTS插件的编译流程中,UTS源码是 Kotlin/swift 源码的上游环节,也就是说 UTS本身就会被编译为Kotlin/swift 源码,所以 uts 与原生语言之间的相互调用 本质是kotlin/swift语言内部 不同函数/对象的调用,不会有任何调用成本和性能损耗
**这是一件很繁琐的事情,`UTS原生混编`的出现彻底解决了这个问题:**
开发者只需要把正确的 kotlin/swift/java 原生代码按照约定放在UTS插件目录中,就可以通过
`uts`
无缝的使用这些原生代码。
在
`UTS插件`
的编译流程中,UTS源码是 Kotlin/swift 源码的上游环节,也就是说 UTS本身就会被编译为Kotlin/swift 源码,所以 uts 与原生语言之间的相互调用 本质是
**同一语言内部 不同函数/对象之间的相互调用,不会有任何调用成本和性能损耗**
和uts插件代码一样,混编的原生代码可以直接真机运行,省去了手动集成AAR三方库需要打包自定义基座的环节,大大提升了开发效率。
...
...
@@ -27,54 +30,64 @@
有了
`UTS原生混编`
之后,开发者如果想要实现对应的原生功能,仅需要:
+
1 通过
搜索引擎/AI/原生API文档
得到原生代码片段,
+
1 通过
`搜索引擎`
/
`AIGC`
/
`原生API`
得到原生代码片段,
+
2 放入UTS插件中,真机运行
即可以看到执行结果
,大大简化了原生功能步骤
。
即可以看到执行结果。
下面我们以内存监控功能为例,分别拆解
在android和ios平台上的实现
步骤
下面我们以内存监控功能为例,分别拆解
`UTS原生混编`
技术在
`Android`
和
`ios`
平台上的使用
步骤
## Android平台
#### 选择UTS插件
#### 前置条件
在真正开始使用
`UTS原生混编`
之前,开发者需要确保两个前置条件:
1
`HBuidlerX`
最低 4.25 版本
2 对
[
UTS插件
](
https://doc.dcloud.net.cn/uni-app-x/plugin/uts-plugin.html#%E7%AE%80%E5%8D%95%E6%8F%92%E4%BB%B6%E7%A4%BA%E4%BE%8B
)
的有基本的认识,和一定的开发经验。
在开始集成之前,你需要确保你拥有一个的UTS插件。
UTS插件创建步骤:
[
参考这里
](
https://doc.dcloud.net.cn/uni-app-x/plugin/uts-plugin.html#%E7%AE%80%E5%8D%95%E6%8F%92%E4%BB%B6%E7%A4%BA%E4%BE%8B
)
在进行下一步的操作之前,你的目录应该是这样的:
![
目录
](
https://web-ext-storage.dcloud.net.cn/doc/uts/uts_hybrid_plugin/bybrid_android_start.png
)
#### 获取和验证原生代码
原生代码的获取一般有三种方式:
#### 第一步 获取和验证原生代码
原生代码的获取有以下方式:
1
[
Android官方文档
](
https://developer.android.google.cn/?hl=zh-cn
)
2 搜索引擎/AI工具
我们在这里使用AI工具通过限定语言得到了原生代码。
我们在这里使用AI工具得到了关键代码:
![
获取代码
](
https://web-ext-storage.dcloud.net.cn/doc/uts/uts_hybrid_plugin/hybrid_android_getcode.png
)
AI工具
和原生
文档得到的代码并不总是准确的,我们需要去验证它。
AI工具
或官方
文档得到的代码并不总是准确的,我们需要去验证它。
目前
HBuilderX并未提供原生代码的语法提示和校验。所以如果编写大段原生代码,推荐在原生ide中编写好,再放入uts插件下混编联调。
目前
`HBuilderX`
并未提供原生代码的语法提示和校验,因此我们建议:
如果是小的代码片段,我们可以通过经验判断或者直接依靠HBuilderX本地编译功能来实现原生代码的校验。
+
如果编写大段原生代码,推荐在原生IDE(比如:AndroidStudo)中编写验证,再放入uts插件混编联调
+
如果是小的代码片段,可以直接放入UTS插件目录,依靠HBuilderX本地编译功能来完成原生代码的校验
这里我们选择直接集成UTS插件, 使用HBuilderX来验证
这里我们选择直接集成UTS插件, 使用
`HBuilderX`
来验证
#### 集成原生代码
####
第二步
集成原生代码
在 kotlin/java语言中,存在包名的概念,在添加原生代码之前,我们要先确保
`Kotlin`
/
`Java`
语言中,存在
[
包名
](
https://kotlinlang.org/docs/packages.html
)
的概念,类似ios中的命名空间。为了让我们的原生代码可以被uts访问到,我们需要确保原生代码的包名是正确的:
大多数情况下,我们建议混编代码的包名与
[
UTS插件默认包名
](
https://doc.dcloud.net.cn/uni-app-x/plugin/uts-for-android.html#_3-1-%E9%85%8D%E7%BD%AEandroidmanifest-xml
)
保持一致,这样在UTS调用原生代码时,可以省去手动引入包名的步骤。
```
kotlin
//
hello uts
混编示例中的包名
package
uts.sdk.modules.uts
Syntaxcase
// 混编示例中的包名
package
uts.sdk.modules.uts
DemoMem
```
如果混编代码的包名与
`UTS插件默认包名`
不一致,则需要像使用原生对象一样手动引入
...
...
@@ -83,37 +96,160 @@ package uts.sdk.modules.utsSyntaxcase
import
KotlinObject
from
'
xxx.xxx.KotlinObject
'
;
```
接下来,我们 在app-android 可以直接添加 kotlin/java 源码
![](
https://web-ext-storage.dcloud.net.cn/doc/uts/uts_plugin/mixCodeAndroid.png
)
整理完的
`Kotlin`
代码是这样的:
> 注意:java代码需要云打包自定义基座后生效,kotlin代码不需要打包,标准基座即可生效
```
kotlin
package
uts.sdk.modules.utsSyntaxcase
// 这里是原生的包名引用
import
android.app.ActivityManager
import
android.content.Context.ACTIVITY_SERVICE
import
io.dcloud.uts.UTSAndroid
import
io.dcloud.uts.setInterval
import
io.dcloud.uts.clearInterval
import
io.dcloud.uts.UTSArray
import
io.dcloud.uts.console
object
NativeCode
{
fun
memMonitor
(){
val
activityManager
=
UTSAndroid
.
getUniActivity
()
?.
getSystemService
(
ACTIVITY_SERVICE
)
as
ActivityManager
val
memoryInfo
=
ActivityManager
.
MemoryInfo
()
activityManager
.
getMemoryInfo
(
memoryInfo
)
val
availMem
=
memoryInfo
.
availMem
/
1024
/
1024
val
totalMem
=
memoryInfo
.
totalMem
/
1024
/
1024
// availMem 可用内存,单位MB
// totalMem 设备内存,单位MB
console
.
log
(
availMem
,
totalMem
)
}
}
```
上面的代码,我们将获取内存的信息的功能以kotlin静态方法的形式对外uts进行暴露。
是的,就是这样简单。如图所示,我们已经完成了原生代码的集成。接下来,我们来编写UTS代码来使用它。
接下来,我们将整理好的原生代码添加到 在
`app-android`
目录
#### 编写uts调用代码
![](
https://web-ext-storage.dcloud.net.cn/doc/uts/uts_hybrid_plugin/bybrid_android_add.png
)
> 注意:java代码需要云打包自定义基座后生效,kotlin代码不需要打包,标准基座即可生效
是的,就是这样简单。如图所示,我们已经完成了原生代码的集成。
#### 在原生代码中调用UTS内置对象
####
第三步
在原生代码中调用UTS内置对象
在上面的示例中,我们已经实现
了使用kotlin代码,获取当前设备内存信息的功能,但是可能我们还想更进一步实现持续监控内存
在上面的示例中,我们已经实现
获取当前设备内存信息的功能,但是可能我们还想更进一步:持续监控内存,并且回调信息到uvue页面
想要实现持续调用的方法有很多,包括在 uvue界面中连续调用等。这里我们为了演示在原生kotlin代码中调用
UTS内置对象的,选择采用
[
setInterval
](
https://doc.dcloud.net.cn/uni-app-x/uts/buildin-object-api/timers.html#setinterval-handler-timeout-arguments
)
函数,实现这个功能:
实现持续调用的方法有很多。这里我们为了演示在原生kotlin代码中调用UTS内置对象,选择采用
[
setInterval
](
https://doc.dcloud.net.cn/uni-app-x/uts/buildin-object-api/timers.html#setinterval-handler-timeout-arguments
)
函数,实现这个功能:
使用 UTS内置对象 需要注意两点:
1 正确引入包名:
1 正确引入类名:
UTS内置对象在具体的平台会有一个对应的类名,举例: Array -> io.dcloud.uts.UTSArray
2 正确的处理 原生对象和内置对象直接的转换
当前示例中不涉及,但如果开发者遇到 kotlin.Array 转换
### 注意事项
完整内置对象和原生对象转换代码示例,大家都可以在具体的内置对象文档上找到。
##### Android包名说明
原生
`kotlin`
代码的最终形态:
```
kotlin
package
uts.sdk.modules.utsDemoMem
import
android.app.ActivityManager
import
android.content.Context.ACTIVITY_SERVICE
import
io.dcloud.uts.UTSAndroid
import
io.dcloud.uts.setInterval
import
io.dcloud.uts.clearInterval
import
io.dcloud.uts.UTSArray
object
NativeCode
{
/**
* 记录上一次的任务id
*/
private
var
lastTaskId
=
-
1
/**
* 开启内存监控
*/
fun
memMonitor
(
callback
:
(
UTSArray
<
Number
>)
->
Unit
){
if
(
lastTaskId
!=
-
1
){
// 避免重复开启
clearInterval
(
lastTaskId
)
}
// 延迟1000ms,每2000ms 获取一次内存
lastTaskId
=
setInterval
({
val
activityManager
=
UTSAndroid
.
getUniActivity
()
?.
getSystemService
(
ACTIVITY_SERVICE
)
as
ActivityManager
val
memoryInfo
=
ActivityManager
.
MemoryInfo
()
activityManager
.
getMemoryInfo
(
memoryInfo
)
val
availMem
=
memoryInfo
.
availMem
/
1024
/
1024
val
totalMem
=
memoryInfo
.
totalMem
/
1024
/
1024
// 将得到的内存信息,封装为UTSArray(即UTS环境中的Array对象)
val
retArray
=
UTSArray
<
Number
>()
retArray
.
add
(
availMem
)
retArray
.
add
(
totalMem
)
callback
(
retArray
)
},
1000
,
2000
)
}
/**
* 关闭内存监控
*/
fun
stopMemMonitor
(){
if
(
lastTaskId
!=
-
1
){
// 避免重复开启
clearInterval
(
lastTaskId
)
}
}
}
```
至此,内存监控功能的原生代码部分已经完全开发完毕。接下来,我们编写UTS代码来使用它。
#### 第三步 编写uts调用代码
如我们在前文所讲,UTS是kotlin语言的上游语言。所有kotlin 代码中的:类、对象、函数、变量,均可以在uts中直接使用。
调用的代码是这样的:
```
ts
export
function
callKotlinCallbackUTS
(
callback
:
(
res
:
string
)
=>
void
)
{
NativeCode
.
kotlinCallbackUTS
(
function
(
res
:
Array
<
number
>
){
console
.
log
(
res
)
callback
(
"
设备内存:
"
+
res
[
0
]
+
"
,可用内存:
"
+
res
[
1
])
})
}
```
#### 注意事项
##### 原生代码使用UTS内置对象
...
...
@@ -136,6 +272,8 @@ console.log("Hello World") // kt或java代码
不过这个导入和使用过程将没有代码提示,输出的变量信息也不会包含变量所在的文件和代码行号等信息。
##### UTS内置对象与原生类型的对应关系
下面列出内置对象对应的类名,如果需要在原生环境和UTS环境/uvue环境中互传数据,建议转换为标准内置对象实现后再进行传递。
|uts 内置对象 |编译成的原生类名
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录