91在线观看视频-91在线观看视频-91在线观看免费视频-91在线观看免费-欧美第二页-欧美第1页

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

【HarmonyOS 5】鴻蒙Web組件和內嵌網頁雙向通信DEMO示例

HarmonyOS解決方案 ? 來源:HarmonyOS解決方案 ? 作者:HarmonyOS解決方案 ? 2025-07-11 18:29 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

HarmonyOS 5】鴻蒙Web組件和內嵌網頁雙向通信DEMO示例

##鴻蒙開發能力 ##HarmonyOS SDK應用服務##鴻蒙金融類應用 (金融理財#

一、前言

在 ArkUI 開發中,Web 組件(Web)允許開發者在應用內嵌入網頁,實現混合開發場景。

本文將通過完整 DEMO,詳解如何通過WebviewController實現 ArkUI 與內嵌網頁的雙向通信,涵蓋 ArkUI 調用網頁 JS、網頁調用 ArkUI 對象的核心技術點。

二、雙向通信實現原理

1、雙向通信概念
Web 到 ArkUI(反向通信)通過registerJavaScriptProxy將 ArkUI 對象注冊到網頁的window對象,允許網頁通過window.xxx調用 ArkUI 暴露的方法。?

ArkUI 到 Web(正向通信)通過runJavaScript執行網頁 JS 代碼,支持回調獲取返回值,實現原生代碼調用網頁函數。

2、雙向通信流程圖
ArkUI Web
┌──────────────┐ ┌──────────────┐
│ registerJS ├─────────────? window.objName │
│ (反向注冊) │ ├──────────────┤
├──────────────┤ │ call test() │
│ runJavaScript├─────────────? execute JS code │
│ (正向調用) │ ├──────────────┤
└──────────────┘ └──────────────┘

三、雙向通信實現步驟

1、ArkUI 定義可被網頁調用的對象
創建一個TestObj類,聲明允許網頁調用的方法(白名單機制):

class TestObj {
  // 網頁可調用的方法1:返回字符串
  test(): string {
    return "ArkUI Web Component";
  }

  // 網頁可調用的方法2:打印日志
  toString(): void {
    console.log('Web Component toString');
  }

  // 網頁可調用的方法3:接收網頁消息
  receiveMessageFromWeb(message: string): void {
    console.log(`Received from web: ${message}`);
  }
}

2、ArkUI 組件核心代碼
初始化控制器與狀態

@Entry
@Component
struct WebComponent {
  // Webview控制器
  controller: webview.WebviewController = new webview.WebviewController();
  // 注冊到網頁的ArkUI對象
  @State testObj: TestObj = new TestObj();
  // 注冊名稱(網頁通過window.[name]訪問)
  @State regName: string = 'objName';
  // 接收網頁返回數據
  @State webResult: string = '';

  build() { /* 組件布局與交互邏輯 */ }
}

布局與交互按鈕,添加三個核心功能按鈕:

Column() {
  // 顯示網頁返回數據
  Text(`Web返回數據:${this.webResult}`).fontSize(16).margin(10);

  // 1. 注冊ArkUI對象到網頁
  Button('注冊到Window')
    .onClick(() = > {
      this.controller.registerJavaScriptProxy(
        this.testObj,  // ArkUI對象
        this.regName,  // 網頁訪問名稱
        ["test", "toString", "receiveMessageFromWeb"]  // 允許調用的方法白名單
      );
    })

  // 2. ArkUI調用網頁JS
  Button('調用網頁函數')
    .onClick(() = > {
      this.controller.runJavaScript(
        'webFunction("Hello from ArkUI!")',  // 執行網頁JS代碼
        (error, result) = > {  // 回調處理返回值
          if (!error) this.webResult = result || '無返回值';
        }
      );
    })

  // 3. Web組件加載
  Web({ src: $rawfile('index.html'), controller: this.controller })
    .javaScriptAccess(true)  // 開啟JS交互權限
    .onPageEnd(() = > {  // 頁面加載完成時觸發
      // 頁面加載后自動調用網頁測試函數
      this.controller.runJavaScript('initWebData()');
    })
}

3. registerJavaScriptProxy的實際作用是,將 ArkUI 對象綁定到網頁window,實現反向通信。

registerJavaScriptProxy(
  obj: Object,        // ArkUI中定義的對象
  name: string,       // 網頁訪問的名稱(如window.name)
  methods: string[]   // 允許調用的方法白名單(嚴格匹配方法名)
);

源碼示例

完整代碼已上傳至Gitee 倉庫,歡迎下載調試!如果有任何問題,歡迎在評論區留言交流~

項目結構
├── xxx.ets # ArkUI組件代碼
└── index.html # 內嵌網頁文件
圖像 20.jpeg

WebViewPage.ets

import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';

class TestObj {
  constructor() {
  }

  test(): string {
    return "ArkUI Web Component";
  }

  toString(): void {
    console.log('Web Component toString');
  }

  receiveMessageFromWeb(message: string): void {
    console.log(`Received message from web: ${message}`);
  }
}

@Entry
@Component
struct WebViewPage {
  controller: webview.WebviewController = new webview.WebviewController();
  @State testObjtest: TestObj = new TestObj();
  @State name: string = 'objName';
  @State webResult: string = '';

  build() {
    Column() {
      Text(this.webResult).fontSize(20)
      Button('refresh')
        .onClick(() = > {
          try {
            this.controller.refresh();
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
          }
        })
      Button('Register JavaScript To Window')
        .onClick(() = > {
          try {
            this.controller.registerJavaScriptProxy(this.testObjtest, this.name, ["test", "toString", "receiveMessageFromWeb"]);
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
          }
        })
      Button('deleteJavaScriptRegister')
        .onClick(() = > {
          try {
            this.controller.deleteJavaScriptRegister(this.name);
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
          }
        })
      Button('Send message to web')
        .onClick(() = > {
          try {
            this.controller.runJavaScript(
              'receiveMessageFromArkUI("Hello from ArkUI!")',
              (error, result) = > {
                if (error) {
                  console.error(`run JavaScript error, ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
                  return;
                }
                console.info(`Message sent to web result: ${result}`);
              }
            );
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
          }
        })
      Button('Get data from web')
        .onClick(() = > {
          try {
            this.controller.runJavaScript(
              'getWebPageData()',
              (error, result) = > {
                if (error) {
                  console.error(`run JavaScript error, ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
                  return;
                }
                if (result) {
                  this.webResult = result;
                  console.info(`Data from web: ${result}`);
                }
              }
            );
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
          }
        })
      Web({ src: $rawfile('index.html'), controller: this.controller })
        .javaScriptAccess(true)
        .onPageEnd(e = > {
          try {
            this.controller.runJavaScript(
              'test()',
              (error, result) = > {
                if (error) {
                  console.error(`run JavaScript error, ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
                  return;
                }
                if (result) {
                  this.webResult = result;
                  console.info(`The test() return value is: ${result}`);
                }
              }
            );
            if (e) {
              console.info('url: ', e.url);
            }
          } catch (error) {
            console.error(`ErrorCode: ${(error as BusinessError).code},  Message: ${(error as BusinessError).message}`);
          }
        })
        .width("100%")
        .height("50%")
    }
    .width("100%")
    .height("100%")
    .backgroundColor(Color.Black)
  }
}

index.html

< !DOCTYPE html >
< html lang="en" >

< head >
    < meta charset="UTF-8" >
    < meta name="viewport" content="width=device-width, initial-scale=1.0" >
    < title >Web Communication< /title >
< /head >


"callArkUIMethod()"< /span?> >Call ArkUI Method< /button >
"sendMessageToArkUI()"< /span?> >Send message to ArkUI< /button >
"messageFromArkUI">
< script >
    function callArkUIMethod() {
        const result = window.objName.test();
        console.log("Result from ArkUI: ", result);
    }

    function sendMessageToArkUI() {
        window.objName.receiveMessageFromWeb('Hello from web!');
    }

    function receiveMessageFromArkUI(message) {
        const messageDiv = document.getElementById('messageFromArkUI');
        messageDiv.textContent = `Received message from ArkUI: ${message}`;
    }

    function getWebPageData() {
        return "Data from web page";
    }

    function test() {
        return "Test function result from web";
    }
< /script >
< /body >

< /html >

注意

組件銷毀時調用deleteJavaScriptRegister(name)取消注冊,避免內存泄漏:

onDestroy() {
  this.controller.deleteJavaScriptRegister(this.regName);
}

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 鴻蒙
    +關注

    關注

    60

    文章

    2617

    瀏覽量

    44032
  • HarmonyOS
    +關注

    關注

    80

    文章

    2126

    瀏覽量

    32979
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    鴻蒙OS開發實例:【Web網頁

    HarmonyOS平臺通過Web控件可支持網頁加載展示,Web在中是作為專項參考的。 本篇文章將從Android和iOS平臺研發角度出發來實踐學習API功能
    的頭像 發表于 03-28 21:47 ?2345次閱讀
    <b class='flag-5'>鴻蒙</b>OS開發實例:【<b class='flag-5'>Web</b><b class='flag-5'>網頁</b>】

    鴻蒙開發基礎-Web組件之cookie操作

    當前會話cookie信息,免去多余的登錄操作。 該頁面布局同樣簡單,由應用導航標題“Web組件”、內部標題“Web組件內”、加載的網頁組成
    發表于 01-14 21:31

    單線雙向通信協議

    請問有沒有什么開放的單線雙向通信協議,想學習下,謝謝
    發表于 06-10 14:57

    tcp/ip雙向通信

    rt,現在有兩個電腦,要通過tcp/ip協議進行雙向通信,單向的收發已經解決了,但是雙向的就不知道該怎么做了,想了兩三個,試過都不行,求大神幫忙,說下思路也好,3q~~~~
    發表于 07-20 23:40

    NRF2401無線模塊的雙向通信怎么實現?

    目前在做一個無線模塊的雙向通信,甲機發一次,乙機收一次,乙機發一次,甲機收一次,就不能雙向通信啦!怎么解決?用的是原子哥的程序!
    發表于 05-18 04:19

    HarmonyOS/OpenHarmony應用開發-Web組件開發體驗

    ;) }}}*附件:HarmonyOSOpenHarmony應用開發-Web組件開發體驗.docx示例效果:參考文檔:https
    發表于 12-12 15:14

    HarmonyOS—使用Web組件加載頁面

    通過調用??loadUrl()??接口加載指定網絡網頁。 在下面的示例中,在Web組件加載完“www.example.com”頁面后,開發者可通過loadUrl接口將此
    發表于 08-31 17:51

    具有雙向通信功能的標準源

    本文介紹的具有雙向通信功能的標準源,是通過串行通信接口將PC機與標準源相連以實現雙向通信功能的系統。PC機的通信功能是利用Visual Basic 6.0這種可視化編程軟件得以實現,標
    發表于 02-25 11:25 ?15次下載

    基于8051的Proteus仿真-單片機之間雙向通信

    基于8051的Proteus仿真-單片機之間雙向通信
    發表于 09-01 23:33 ?17次下載

    DSPeCAN總線中斷方式與上位機的雙向通信

    DSPeCAN總線中斷方式與上位機的雙向通信
    發表于 10-20 10:57 ?5次下載
    DSPeCAN總線中斷方式與上位機的<b class='flag-5'>雙向通信</b>

    鴻蒙ArkTS聲明式組件Web

    提供具有網頁顯示能力的Web組件,[@ohos.web.webview]提供web控制能力。
    的頭像 發表于 07-04 15:35 ?1395次閱讀
    <b class='flag-5'>鴻蒙</b>ArkTS聲明式<b class='flag-5'>組件</b>:<b class='flag-5'>Web</b>

    HarmonyOS 5鴻蒙頁面和組件生命周期函數

    HarmonyOS 5鴻蒙頁面和組件生命周期函數 ##鴻蒙開發能力 ##HarmonyOS
    的頭像 發表于 07-11 18:24 ?269次閱讀

    HarmonyOS 5鴻蒙星閃NearLink詳解

    HarmonyOS 5鴻蒙星閃NearLink詳解 ##鴻蒙開發能力 ##HarmonyOS SDK應用服務##
    的頭像 發表于 07-11 18:24 ?293次閱讀
    【<b class='flag-5'>HarmonyOS</b> <b class='flag-5'>5</b>】<b class='flag-5'>鴻蒙</b>星閃NearLink詳解

    HarmonyOS 5】金融應用開發鴻蒙組件實踐

    HarmonyOS 5】金融應用開發鴻蒙組件實踐 ##鴻蒙開發能力 ##HarmonyOS S
    的頭像 發表于 07-11 18:20 ?272次閱讀
    【<b class='flag-5'>HarmonyOS</b> <b class='flag-5'>5</b>】金融應用開發<b class='flag-5'>鴻蒙</b><b class='flag-5'>組件</b>實踐

    HarmonyOS 5 入門系列 】鴻蒙HarmonyOS示例項目講解

    HarmonyOS 5 入門系列 】鴻蒙HarmonyOS示例項目講解 ##鴻蒙開發能力 #
    的頭像 發表于 07-07 11:57 ?143次閱讀
    【 <b class='flag-5'>HarmonyOS</b> <b class='flag-5'>5</b> 入門系列 】<b class='flag-5'>鴻蒙</b><b class='flag-5'>HarmonyOS</b><b class='flag-5'>示例</b>項目講解
    主站蜘蛛池模板: 国产99色| 一级片视频播放 | 日不卡| 亚洲黄色第一页 | 五月天天爱 | 天天噜噜日日噜噜久久综合网 | 天天插在线视频 | 国产毛片农村妇女aa板 | 四虎成人免费影院网址 | 日本黄色免费观看 | 午夜天堂影院 | 黄色爱爱视频 | 午夜色在线 | 天天透天天操 | 丁香五月缴情在线 | 亚色成人| 日韩有码电影 | 2018天天操夜夜操 | 人人骚 | 曰本性l交片视频视频 | 日本一本视频 | 婷婷色影院 | 亚洲乱码中文字幕综合 | 国产成人啪精品午夜在线播放 | 一夜七次郎久久综合伊人 | 国产成人在线影院 | 天天干天天干天天干天天干天天干 | 色偷偷91综合久久噜噜噜男男 | 欧美性网 | 人人干在线 | 亚洲成片在线观看12345ba | 亚洲一区精品中文字幕 | 日本黄色录象 | 国产精品三级 | 午夜影院免费在线观看 | 国产男女怕怕怕免费视频 | 天天操天天碰 | 国产亚洲美女精品久久久2020 | 国产免费卡1卡2卡 | 久久久久久免费观看 | 夜恋秀场欧美成人影院 |