鸿蒙网络编程系列24-Web组件与应用互操作示例

news2024/11/28 10:42:24

1. APP内嵌网页与应用互操作概述

在通常的APP开发中,经常会采用内嵌网页的形式,通过网页来展现丰富的动态内容,虽少了很多原生开发的功能,但是这么做无可厚非,毕竟APP需要适配的系统平台很多,比如安卓、苹果、各种PC端,现在还有如日中天的鸿蒙系统;为每一种平台做定制难度还是很大的,但是这些平台的APP都支持内嵌网页,通过网页可以屏蔽各平台的差异,从而减少开发难度,提高开发效率。

当然,单纯的内嵌网页还是有不少局限性的,不过,可以通过应用和网页的互操作来提升用户的使用体验,所谓的互操作,就是可以在网页中调用APP中的方法,或者在APP中执行网页中的脚本,鸿蒙通过web组件中的javaScriptProxy接口提供了注册应用侧js对象到web组件中的方法:

javaScriptProxy(javaScriptProxy: { object: object, name: string, methodList: Array<string>,controller: WebviewController | WebController, asyncMethodList?: Array<string>})

当然,也可以使用WebviewController的registerJavaScriptProxy接口:

registerJavaScriptProxy(object: object, name: string, methodList: Array<string>, asyncMethodList?: Array<string>): void

在应用侧执行网页中的脚本使用的是WebviewController类的runJavaScript接口:

runJavaScript(script: string): Promise<string>

通过上述几个接口,就可以实现强大的Web组件与应用互操作功能

2. Web组件与应用互操作示例

本示例运行后的界面如下所示

cke_69536.jpg

单击网页中“计算应用侧的乘法”按钮,可以自动计算app上部的乘法,计算后的界面如下所示;

cke_126606.jpg

在app内调节RGB颜色分量,设置好选择的背景色后,单击应用中的“设置网页背景色”按钮,可以设置网页的背景色:

cke_139796.jpg

下面详细介绍创建该应用的步骤。

步骤1:创建Empty Ability项目。

步骤2:在module.json5配置文件加上对权限的声明:

"requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      }
    ]

这里添加了获取互联网信息的权限。

步骤3:添加资源文件demo.html,路径为src/main/resources/rawfile/demo.html,内容如下:

<!-- index.html -->
<!DOCTYPE html>
<html>
<meta charset="utf-8">
​
<body>
  <div style="text-align: center;font-size: larger;">
    <button type="button" onclick="compute()">计算应用侧的乘法</button>
  </div>
  <div id="info">
​
  </div>
</body>
<script type="text/javascript">
  function compute() {
    let multiplier = multipObj.getMultiplier();
    let multiplicand = multipObj.getMultiplicand();
    let product = multiplier * multiplicand
    multipObj.setProduct(product);
  }
​
  function setbackcolor(color) {
    document.body.style.backgroundColor = color;
  }
</script>
​
</html>

该资源文件很重要,是本示例互操作实现的基础。

步骤4:在Index.ets文件里添加如下的代码:

import web_webview from '@ohos.web.webview'
​
//注册到web组件中的应用侧js对象
class ComputeObj {
  constructor() {
  }
​
  public multiplier: number = 0.618
  public multiplicand: number = 3.14
  public product: string = "乘积"
​
  //获取乘数
  public getMultiplier() {
    return this.multiplier;
  }
​
  //获取被乘数
  public getMultiplicand() {
    return this.multiplicand;
  }
​
  //设置乘积
  public setProduct(newProduct: number) {
    this.product = newProduct.toString();
  }
}
​
@Entry
@Component
struct Index {
  @State computeObj: ComputeObj = new ComputeObj()
  jsName: string = "multipObj"
  @State rColor: number = 100
  @State gColor: number = 100
  @State bColor: number = 100
  @State backColor: string = "#646464"
  scroller: Scroller = new Scroller()
  controller: web_webview.WebviewController = new web_webview.WebviewController()
​
  build() {
    Row() {
      Column() {
        Text("Web组件与应用互操作示例")
          .fontSize(14)
          .fontWeight(FontWeight.Bold)
          .width('100%')
          .textAlign(TextAlign.Center)
          .padding(5)
​
        Text("输入乘数和被乘数,在web组件中单击计算按钮进行计算")
          .fontSize(14)
          .width('100%')
          .textAlign(TextAlign.Start)
          .padding(5)
​
        Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
          TextInput({ text: this.computeObj.multiplier.toString() })
            .onChange((value) => {
              this.computeObj.multiplier = parseFloat(value)
            })
            .type(InputType.NUMBER_DECIMAL)
            .width(110)
            .fontSize(11)
            .flexGrow(1)
​
          Text("*")
            .fontSize(14)
            .width(20)
            .flexGrow(0)
​
          TextInput({ text: this.computeObj.multiplicand.toString() })
            .onChange((value) => {
              this.computeObj.multiplicand = parseFloat(value)
            })
            .type(InputType.NUMBER_DECIMAL)
            .width(100)
            .fontSize(11)
            .flexGrow(1)
​
          Text("=")
            .fontSize(14)
            .width(20)
            .flexGrow(0)
​
          TextInput({ text: `${this.computeObj.product}` })
            .width(100)
            .fontSize(11)
            .enabled(false)
            .flexGrow(1)
        }
        .width('100%')
        .padding(5)
​
        Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
          Text("R颜色分量")
            .fontSize(14)
            .width(100)
            .flexGrow(0)
​
          Slider({ value: this.rColor, min: 0, max: 255 })
            .onChange((value: number, mode: SliderChangeMode) => {
              this.rColor = value
              this.computeBackcolor()
            })
            .flexGrow(1)
        }
        .width('100%')
        .padding(5)
​
        Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
          Text("G颜色分量")
            .fontSize(14)
            .width(100)
            .flexGrow(0)
​
          Slider({ value: this.gColor, min: 0, max: 255 })
            .onChange((value: number, mode: SliderChangeMode) => {
              this.gColor = value
              this.computeBackcolor()
            })
            .flexGrow(1)
        }
        .width('100%')
        .padding(5)
​
        Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
          Text("B颜色分量")
            .fontSize(14)
            .width(100)
            .flexGrow(0)
​
          Slider({ value: this.bColor, min: 0, max: 255 })
            .onChange((value: number, mode: SliderChangeMode) => {
              this.bColor = value
              this.computeBackcolor()
            })
            .flexGrow(1)
        }
        .width('100%')
        .padding(5)
​
        Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) {
          Text(`选中的颜色:${this.backColor}`)
            .fontSize(14)
            .height(30)
            .width(150)
            .backgroundColor(this.backColor)
​
          Button("设置网页背景色")
            .onClick(() => {
              this.controller.runJavaScript(`setbackcolor('${this.backColor}')`)
            })
            .width(140)
            .fontSize(14)
            .flexGrow(0)
        }
        .width('100%')
        .padding(5)
​
        Scroll(this.scroller) {
          Web({ src: $rawfile("demo.html"), controller: this.controller })
            .padding(10)
            .width('100%')
            .textZoomRatio(300)
            .backgroundColor(0xeeeeee)
            //注册js对象
            .javaScriptProxy({
              object: this.computeObj,
              name: this.jsName,
              methodList: ["getMultiplier", "getMultiplicand", "setProduct"],
              controller: this.controller,
            })
        }
        .align(Alignment.Top)
        .backgroundColor(0xeeeeee)
        .height(300)
        .flexGrow(1)
        .scrollable(ScrollDirection.Vertical)
        .scrollBar(BarState.On)
        .scrollBarWidth(20)
      }
      .width('100%')
      .justifyContent(FlexAlign.Start)
      .height('100%')
    }
    .height('100%')
  }
​
  //计算背景色
  computeBackcolor() {
    this.backColor = "#" + parseInt(this.rColor.toFixed(0)).toString(16)
      + parseInt(this.gColor.toFixed(0)).toString(16)
      + parseInt(this.bColor.toFixed(0)).toString(16)
  }
}

步骤5:编译运行,可以使用模拟器或者真机。

步骤6:具体的操作过程上面讲过了,就不再赘述了。

3. 关键功能分析

第一个是要注册到web组件中的js对象,在API12中写成class的形式,

//注册到web组件中的应用侧js对象
class ComputeObj {
  constructor() {
  }
​
  public multiplier: number = 0.618
  public multiplicand: number = 3.14
  public product: string = "乘积"
​
  //获取乘数
  public getMultiplier() {
    return this.multiplier;
  }
​
  //获取被乘数
  public getMultiplicand() {
    return this.multiplicand;
  }
​
  //设置乘积
  public setProduct(newProduct: number) {
    this.product = newProduct.toString();
  }
}

第二个是注册对象的代码:

Web({ src: $rawfile("demo.html"), controller: this.controller })
            .padding(10)
            .width('100%')
            .textZoomRatio(300)
            .backgroundColor(0xeeeeee)
            //注册js对象
            .javaScriptProxy({
              object: this.computeObj,
              name: this.jsName,
              methodList: ["getMultiplier", "getMultiplicand", "setProduct"],
              controller: this.controller,
            })

这里javaScriptProxy方法的各个参数一定要保证准确,否则在web组件中调用会失败,其中name和demo.html中使用的注册对象名称multipObj要完全一致,methodList参数为注册对象声明的方法,也要保证拼写正确。

最后是计算背景的代码:

  //计算背景色
  computeBackcolor() {
    this.backColor = "#" + parseInt(this.rColor.toFixed(0)).toString(16)
      + parseInt(this.gColor.toFixed(0)).toString(16)
      + parseInt(this.bColor.toFixed(0)).toString(16)
  }

把选中的颜色分量拼凑成了颜色字符串,最前面的是字符#。

(本文作者原创,除非明确授权禁止转载)

本文源码地址:

https://gitee.com/zl3624/harmonyos_network_samples/tree/master/code/web/WebAppInteropDemo

本系列源码地址:

https://gitee.com/zl3624/harmonyos_network_samples

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2219010.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

leetcode289:生命游戏

根据 百度百科 &#xff0c; 生命游戏 &#xff0c;简称为 生命 &#xff0c;是英国数学家约翰何顿康威在 1970 年发明的细胞自动机。 给定一个包含 m n 个格子的面板&#xff0c;每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态&#xff1a; 1 即为 活细胞 &am…

babylonjs shader学习之copy shadertoy案例

shadertoy案例&#xff1a; 准备 const onSceneReady (scene: Scene) > {const light new HemisphericLight(light, new Vector3(0, 1, 0), scene);light.intensity 0.7;Effect.ShadersStore[planeMatVertexShader] precision highp float;attribute vec3 position;attr…

SpringMVC一个拦截器和文件上传下载的完整程序代码示例以及IDEA2024部署报错 找不到此 Web 模块的 out\artifacts\..问题

一、SpringMVC一个拦截器和文件上传下载的完整程序代码示例 本文章是一个 SpringMVC拦 截器和文件上传下载的完整程序代码示例&#xff0c;使用的开发工具是 IntelliJ IDEA 2024.1.6 (Ultimate Edition)&#xff0c; 开发环境是 OpenJDK-21 java version 21.0.2。Tomcatt版本为…

Flux.concat 使用说明书

public static <T> Flux<T> concat(Iterable<? extends Publisher<? extends T>> sources)Concatenate all sources provided in an Iterable, forwarding elements emitted by the sources downstream. 连接可迭代集合中提供的所有源&#xff0c;将…

【web】JDBC

项目连接数据库 右侧导航栏找到databsae 如果没有驱动&#xff0c;先下载驱动 填写数据库用户名密码 勾选对应的表即可 JDBC代码流程 1,配置信息 2,加载驱动 从MySQL Connector/J 5.1版本开始&#xff0c;推荐使用com.mysql.cj.jdbc.Driver这个新的驱动类。 3,链接数据库…

【MR开发】在Pico设备上接入MRTK3(三)——在Unity中运行MRTK示例

在前面的文档中&#xff0c;介绍了如何在Unity工程中配置号MRTK和Pico SDK 【MR开发】在Pico设备上接入MRTK3&#xff08;一&#xff09;在Unity中导入MRTK3依赖【MR开发】在Pico设备上接入MRTK3&#xff08;二&#xff09;在Unity中配置Pico SDK 本文将介绍如何运行一个简单…

SQL进阶技巧:如何找出开会时间有重叠的会议室?| 时间区间重叠问题

目录 0 场景描述 1 数据准备 2 问题分析 方法1:利用 lateral view posexplode()函数将表展开成时间明细表 方法2:利用数学区间讨论思想求解 3 小结 0 场景描述 有7个会议室,每个会议室每天都有人开会,某一天的开会时间如下: 查询出开会时间有重叠的是哪几个会议室?…

Agentic RAG(基于智能体的检索增强生成)是检索增强生成(Retrieval-Augmented Generation,RAG)技术的一种高级形式

Agentic RAG&#xff08;基于智能体的检索增强生成&#xff09;是检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;RAG&#xff09;技术的一种高级形式&#xff0c;它通过引入人工智能代理&#xff08;Agent&#xff09;的概念&#xff0c;为语言模型赋予了…

C#从零开始学习(用unity探索C#)(unity Lab1)

初次使用Unity 本章所有的代码都放在 https://github.com/hikinazimi/head-first-Csharp Unity的下载与安装 从 unity官网下载Unity Hub Unity的使用 安装后,注册账号,下载unity版本,然后创建3d项目 设置窗口界面布局 3D对象的创建 点击对象,然后点击Move Guzmo,就可以拖动…

018_FEA_Structure_Static_in_Matlab三维结构静力学分析

刹车变形分析 本示例展示了如何使用 MATLAB 软件进行刹车变形分析。 这个例子是Matlab官方PDE工具箱的第一个例子&#xff0c;所需要的数据文件都由Matlab提供&#xff0c;包括CAD模型文件。 步骤 1: 导入 CAD 模型 导入 CAD 模型&#xff0c;这里使用的是一个带有孔的支架模…

HTTP cookie 与 session

一种关于登录的场景演示 - B 站登录和未登录 问题&#xff1a;B 站是如何认识我这个登录用户的&#xff1f;问题&#xff1a;HTTP 是无状态&#xff0c;无连接的&#xff0c;怎么能够记住我&#xff1f; 一、引入 HTTP Cookie 定义 HTTP Cookie&#xff08;也称为 Web Cooki…

【最新华为OD机试E卷-支持在线评测】VLAN资源池(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…

R语言复杂抽样调查数据统计描述和分析

gtsummary包中tbl_svysummary提供了统计描述&#xff1b;tableone包中的svyCreateTableOne提供了统计比较&#xff1b;原始描述和比较可以是有table1包。 #测试数据 library(survey) setwd("F://") data(Titanic) sur_des<-survey::svydesign(~1, data as.data.…

Leetcode—1117. H2O 生成【中等】(多线程)

2024每日刷题&#xff08;182&#xff09; Leetcode—1117. H2O 生成 C实现代码 class H2O { public:H2O() {sem_init(&hydrogenSem, 0, 1);sem_init(&oxygenSem, 0, 0);}~H2O() {sem_destroy(&hydrogenSem);sem_destroy(&oxygenSem);}void hydrogen(functio…

重学SpringBoot3-Spring WebFlux简介

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-Spring WebFlux简介 1. 什么是 WebFlux&#xff1f;2. WebFlux 与 Spring MVC 的区别3. WebFlux 的用处3.1 非阻塞 I/O 操作3.2 响应式编程模型3.3 更高…

机械视觉光源选型

光源是机器视觉系统的重要组成部分&#xff0c;直接影响到图像的质量&#xff0c;进而影响到系统的性 能。在一定程度上&#xff0c;光源的设计与选择是机器视觉系统成败的关键。光源最重要的功能就 是使被观察的图像特征与被忽略的图像特征之间产生最大的对比度&#xff0c;…

RISC-V笔记——RVWMO基本体

1. 前言 RISC-V使用的内存模型是RVWMO(RISC-V Weak Memory Ordering)&#xff0c;它是Release Consistency的扩展&#xff0c;因此&#xff0c;RVWMO的基本特性类似于RC模型。 2. RC模型 Release consistency(RC)的提出是基于一个观察&#xff1a;将所有同步操作用FENCE围在一…

基于x86_64汇编语言简单教程1: 环境预备与尝试

目录 前言 环境配置 基本硬件与操作系统要求 WSL VSCode基本配置(For Windows) 安装基本的依赖 为您的VSCode安装插件&#xff1a; 学习要求 入门 先试试味道 前言 笔者最近正在梭哈使用NASM汇编器的x86 32位汇编&#xff0c;笔者这里记录一下一个晚上的成果。 环境…

【含开题报告+文档+PPT+源码】贫困儿童一对一扶贫帮扶系统设计与实现

开题报告 根据《中华人民共和国慈善法》第五十八条规定&#xff0c;慈善组织确定慈善受益人&#xff0c;应当坚持公开、公平、公正的原则&#xff0c;不得指定慈善组织管理人员的利害关系人作为受益人[2]。以上所列举的平台基本没有做到公开、公平、公正的原则&#xff0c;例如…

一起搭WPF架构之livechart的MVVM使用介绍

一起搭WPF架构之livechart使用介绍 前言ModelViewModelView界面设计界面后端 效果总结 前言 简单的架构搭建已经快接近尾声了&#xff0c;考虑设计使用图表的形式将SQLite数据库中的数据展示出来。前期已经介绍了livechart的安装&#xff0c;今天就详细介绍一下livechart的使用…