提交 42588701 编写于 作者: 杜庆泉's avatar 杜庆泉

更新uts插件混编文档

上级 3a9b9b59
# UTS原生混编介绍 # 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三方库需要打包自定义基座的环节,大大提升了开发效率。 和uts插件代码一样,混编的原生代码可以直接真机运行,省去了手动集成AAR三方库需要打包自定义基座的环节,大大提升了开发效率。
...@@ -27,54 +30,64 @@ ...@@ -27,54 +30,64 @@
有了`UTS原生混编`之后,开发者如果想要实现对应的原生功能,仅需要: 有了`UTS原生混编`之后,开发者如果想要实现对应的原生功能,仅需要:
+ 1 通过搜索引擎/AI/原生API文档 得到原生代码片段, + 1 通过`搜索引擎`/`AIGC`/`原生API` 得到原生代码片段,
+ 2 放入UTS插件中,真机运行 + 2 放入UTS插件中,真机运行
即可以看到执行结果,大大简化了原生功能步骤 即可以看到执行结果。
下面我们以内存监控功能为例,分别拆解 在android和ios平台上的实现步骤 下面我们以内存监控功能为例,分别拆解 `UTS原生混编`技术在`Android``ios`平台上的使用步骤
## Android平台 ## 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) 1 [Android官方文档](https://developer.android.google.cn/?hl=zh-cn)
2 搜索引擎/AI工具 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调用原生代码时,可以省去手动引入包名的步骤。 大多数情况下,我们建议混编代码的包名与[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 ```kotlin
// hello uts 混编示例中的包名 // 混编示例中的包名
package uts.sdk.modules.utsSyntaxcase package uts.sdk.modules.utsDemoMem
``` ```
如果混编代码的包名与`UTS插件默认包名`不一致,则需要像使用原生对象一样手动引入 如果混编代码的包名与`UTS插件默认包名`不一致,则需要像使用原生对象一样手动引入
...@@ -83,37 +96,160 @@ package uts.sdk.modules.utsSyntaxcase ...@@ -83,37 +96,160 @@ package uts.sdk.modules.utsSyntaxcase
import KotlinObject from 'xxx.xxx.KotlinObject'; 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代码中调用 实现持续调用的方法有很多。这里我们为了演示在原生kotlin代码中调用UTS内置对象,选择采用[setInterval](https://doc.dcloud.net.cn/uni-app-x/uts/buildin-object-api/timers.html#setinterval-handler-timeout-arguments)函数,实现这个功能:
UTS内置对象的,选择采用[setInterval](https://doc.dcloud.net.cn/uni-app-x/uts/buildin-object-api/timers.html#setinterval-handler-timeout-arguments)函数,实现这个功能:
使用 UTS内置对象 需要注意两点: 使用 UTS内置对象 需要注意两点:
1 正确引入包名: 1 正确引入类名:
UTS内置对象在具体的平台会有一个对应的类名,举例: Array -> io.dcloud.uts.UTSArray
2 正确的处理 原生对象和内置对象直接的转换 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内置对象 ##### 原生代码使用UTS内置对象
...@@ -136,6 +272,8 @@ console.log("Hello World") // kt或java代码 ...@@ -136,6 +272,8 @@ console.log("Hello World") // kt或java代码
不过这个导入和使用过程将没有代码提示,输出的变量信息也不会包含变量所在的文件和代码行号等信息。 不过这个导入和使用过程将没有代码提示,输出的变量信息也不会包含变量所在的文件和代码行号等信息。
##### UTS内置对象与原生类型的对应关系
下面列出内置对象对应的类名,如果需要在原生环境和UTS环境/uvue环境中互传数据,建议转换为标准内置对象实现后再进行传递。 下面列出内置对象对应的类名,如果需要在原生环境和UTS环境/uvue环境中互传数据,建议转换为标准内置对象实现后再进行传递。
|uts 内置对象 |编译成的原生类名 |uts 内置对象 |编译成的原生类名
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册