移动端最常用&最重要组件之一:WebView(HarmonyOS版)使用指南

系统 OpenHarmony
本期Codelab我们将用一个Demo来详细介绍WebView组件的使用,包括UI界面的创建、WebView组件创建、Web页面加载方式、APP应用与Web页面间的交互与通信四个方面内容。

[[400182]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

现在很多APP里都内置了Web页面(比如社交APP、新闻浏览类APP),即从APP中跳转到网络Web页面或本地Web页面,这种方法便于扩展APP应用体验和更新维护内置Web页面。在HarmonyOS中,开发者可以通过WebView组件实现上述功能。

WebView组件可用于加载网页内容、获取页面详细信息和控制页面跳转,并实现APP应用与内置Web页面间的交互和通信。

本期Codelab我们将用一个Demo来详细介绍WebView组件的使用,包括UI界面的创建、WebView组件创建、Web页面加载方式、APP应用与Web页面间的交互与通信四个方面内容。

在开始敲代码之前,开发者们需要先下载安装Huawei DevEco Studio,可参照官网的指南进行操作:

·Huawei DevEco Studio安装指南:

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415

接下来我们来解析本次Demo的代码结构,方便大家做一个初步的了解:

● MainAbilitySlice文件

“MainAbilitySlice”文件在slice文件夹中,主要用于实现Demo逻辑,包括获取WebView对象,加载页面和实现Web页面间的通信及交互。

● DataAbility文件

“DataAbility”文件主要是通过DataAbility访问WebView加载的本地文件。

● background_button.xml文件

“background_button.xml”文件在graphic文件夹中,主要用于实现Demo中按钮的背景设置。

● ability_main.xml文件

“ability_main.xml”文件在layout文件夹中,主要实现WebView组件的创建,同时也进行诸如文本输入框和按钮等其他UI界面内容的创建。

● text.html文件

“text.html”文件在rawfile文件夹中,是新增本地Web页面的HTML文件,用于模拟WebView需要加载的本地Web页面。

● config.json文件

config.json文件是工程相关配置文件,这里主要用于添加WebView加载Web页面所需的网络权限申请和DataAbility的声明。

了解完基本的代码结构,我们正式进入WebView组件的使用。

UI页面的创建

我们先来创建一个UI界面(如图1 Demo的UI界面),该界面将包含:

◆ TextField组件,用于接收用户输入的网址信息,本Demo中默认网址为

https://www.huawei.com/cn/;

◆ WebView组件,本Demo的重点组件,我们将在“WebView组件创建”中详细描述;

◆ Button组件,即按钮组件,本次Demo主界面中涉及5个按钮组件将实现以下功能:加载Web页面(Load URL)、Web网页向后预览(Go Back)、向前浏览(GO Forward)、加载本地HTML页面(Load Local HTML)和给本地网页发信息(Send Message to Local HTML)。

WebView组件创建

WebView派生于通用组件Component,包含基本组件的所有功能,可以像普通组件一样使用。也就是说,WebView组件同样可以采用XML形式和代码形式创建,本次Demo使用的是XML形式:

1. 在"ability_main.xml"文件中创建WebView,示例代码如下:

  1. <ohos.agp.components.webengine.WebView  
  2.     ohos:id="$+id:webview"  
  3.     ohos:height="match_parent"  
  4.     ohos:width="match_parent">  
  5. </WebView> 

 2.在"slice/MainAbilitySlice.java"文件中通过如下方式获取WebView对象,示例代码如下:

  1. WebView webview = (WebView)  
  2. findComponentById(ResourceTable.Id_webview); 

 当然,开发者也可以使用代码形式创建,详情请参考官网:

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-java-component-webview-0000001092715158

Web页面加载

WebView如何加载网络Web页面和本地Web页面呢?接下来我们将分别进行介绍。

1.WebView加载网络Web页面

加载网络Web页面需要申请网络权限ohos.permission.INTERNET。

我们在config.json中添加如下代码进行申请:

  1. module": {  
  2. ……  
  3.    "reqPermissions": [  
  4.     {  
  5.        "name""ohos.permission.INTERNET"  
  6.      }  
  7.   ]  

 完成网络申请后,在"MainAbilitySlice.java"文件中通过webview.load(String url)方法访问具体的网络Web页面,通过WebConfig类对WebView组件进行配置,示例代码如下:

  1. WebConfig webConfig = webview.getWebConfig();  
  2. // WebView加载URL,其中urlTextField为输入URL的TextField组件  
  3. webview.load(urlTextField.getText()); 

 在Web页面进行链接跳转时,WebView默认会打开目标网址,通过WebAgent对象可以捕获该行为,这里仅使用isNeedLoadUrl根据当前WebView请求检查是否加载请求,当URL以"http:"或"https:"开头,则执行加载,示例代码如下:

  1. webview.setWebAgent(new WebAgent() {  
  2.             @Override  
  3.             public boolean isNeedLoadUrl(WebView webView, ResourceRequest request) {  
  4.                 if (request == null || request.getRequestUrl() == null) {  
  5.                     LogUtil.info(TAG,"WebAgent isNeedLoadUrl:request is null.");  
  6.                     return false;  
  7.                 }  
  8.                 String url = request.getRequestUrl().toString();  
  9.                 if (url.startsWith("http:") || url.startsWith("https:")) {  
  10.                     webView.load(url);  
  11.                     return false;  
  12.                 } else {  
  13.                     return super.isNeedLoadUrl(webView, request);  
  14.                 }  
  15.             }  
  16.         }); 

 除此之外,WebAgent对象还提供了相关的回调函数以观测页面状态的变更,如onLoadingPage、onPageLoaded、onError等方法,用于页面“开始加载”、“停止加载”、“加载错误”时的调用,详情可见官网WebAgent参考。

·官网:WebAgent参考

https://developer.harmonyos.com/cn/docs/documentation/doc-references/webagent-0000001078160526

同时,WebView提供Navigator类进行历史记录的浏览和处理,开发者可通过getNavigator()方法获取该类的对象,使用canGoBack()或canGoForward()方法检查是否可以向后或向前浏览,使用goBack()或goForward()方法实现向后或向前浏览,示例代码如下:

  1. Navigator navigator = webView.getNavigator();  
  2. if (navigator.canGoBack()) {  
  3.     navigator.goBack();  
  4. }  
  5. if (navigator.canGoForward()) {  
  6.     navigator.goForward();  

 2.WebView加载本地Web页面

出于安全考虑,WebView不支持直接通过File协议加载资源文件或本地文件。如开发者需实现相关业务,HarmonyOS提供两种方式:通过processResourceRequest方法访问文件和通过Data Ability访问文件。

在本Demo中,我们将重点讲述Data Ability访问文件的形式,大家可以通过官网了解processResourceRequest方法的实现~

·官网:加载资源文件或本地文件

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-java-component-webview-0000001092715158

本次Demo中,我们将自行创建一个HTML文件,放在"resources/rawfile/"目录下并将其命名为text.html。除了HTML文件常见的固定内容,我们还将在其中加入<button>标签,用于生成按钮“调用Java方法”和添加<script >插入一段JavaScript内容,示例代码如下:

  1. <!DOCTYPE html>  
  2. <html>  
  3.     <meta charset="UTF-8">  
  4.     <title>本地html</title>  
  5.     <body onload="hello">  
  6.         <br>  
  7.         <h1 id="helloName">这是一个本地HTML页面</h1>  
  8.         <br>  
  9.         <button id="button" onclick="sendData()" style="background-color:#70DBDB;height:30px;">调用Java方法</button>  
  10.   
  11.         <script type="text/javascript"
  12.         …….// 省略部分为应用调用Web页面及/ Web页面调用应用内容,我们将在后续讲解 
  13. </script>  
  14.     </body>  
  15. </html> 

创建完本地Web页面,我们来看看WebView如何通过DataAbility加载本地Web页面。如果不了解DataAbility的具体使用方法,可以参考官网链接。

·官网:DataAbility

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ability-data-concept-0000000000043058

1)我们新建一个DataAbility。注意使用DataAbility之前需要先完成声明,我们在"entry\src\main\config.json"中完成,示例代码如下:

  1. module": {  
  2. ……  
  3.    "abilities": [  
  4.     {  
  5.       "name""com.huawei.codelab.DataAbility",  
  6.       "type""data",  
  7.       "uri""dataability://com.huawei.codelab.DataAbility"  
  8.     }  
  9.   ]  

 2)通过openRawFile(Uri uri, String mode)方法,完成WebView对本地Web页面的访问,示例代码如下:

  1. public class DataAbility extends Ability {  
  2.     ...  
  3.     @Override  
  4.     public RawFileDescriptor openRawFile(Uri uri, String mode) throws FileNotFoundException {  
  5.         if (uri == null) {;  
  6.             return super.openRawFile(uri, mode);  
  7.         }  
  8.         String path = uri.getEncodedPath();  
  9.         int splitIndex = path.indexOf('/', 1);  
  10.         String providerName = Uri.decode(path.substring(1, splitIndex));  
  11.         String rawFilePath = Uri.decode(path.substring(splitIndex + 1));  
  12.         RawFileDescriptor rawFileDescriptor = null;  
  13.         try {  
  14.             rawFileDescriptor = getResourceManager().getRawFileEntry(rawFilePath).openRawFileDescriptor();  
  15.         } catch (IOException e) {  
  16.             // 异常处理  
  17.         }  
  18.         return rawFileDescriptor;  
  19.     }  

 3)在"slice/MainAbilitySlice.java"中声明需要访问的文件路径,通过webview.load(String url)方法加载本地Web页面,可以通过WebConfig类的对象对WebView访问DataAbility的能力进行配置,示例代码如下:

  1. private static final String URL_LOCAL = "dataability://com.huawei.codelab.DataAbility/resources/rawfile/test.html";  
  2. // 配置是否支持访问DataAbility资源,默认为true  
  3. webConfig.setDataAbilityPermit(true);  
  4. webview.load(URL_LOCAL); 

 APP应用与Web页面间的通信与交互

APP应用和内置Web页面其实是相互独立的,彼此之间是相互隔断的,它们需要通过WebVeiw组件实现相互调用,来完成诸如获取信息、接收弹窗、关闭弹窗等功能。

这个时候需要APP应用和Web页面之间进行通信与交互,那具体是如何实现的,让我们以本地Web页面"text.html"为例来介绍一下。

首先我们需要对WebView组件中的WebConfig对象进行配置,使APP应用能与Web页面中的JavaScript脚本交互,在MainAbilitySlice中实现,示例代码如下:

  1. // 配置是否支持JavaScript,默认值为false  
  2. webConfig.setJavaScriptPermit(true); 

 1.APP应用调用本地Web页面

我们先来介绍一下APP应用调用Web页面的情况。在" text.html"文件中编写callJS方法,待APP应用调用,示例代码如下

  1. <script type="text/javascript">  
  2.     // 应用调用Web页面  
  3.     function callJS(message) {  
  4.         alert(message);  
  5.     }  
  6. </script> 

在"slice/MainAbilitySlice.java"中实现APP应用对Web页面JavaScript的调用,示例代码如下:

  1. webview.executeJs("javascript:callJS('这是来自JavaSlice的消息')", msg -> {  
  2.         // 在这里处理Js方法的返回值  
  3.     }); 

 当我们点击“Send Message to Local HTML”按钮时呈现效果如图2所示:

我们还可以通过setBrowserAgent方法设置自定义BrowserAgent对象,以观测JavaScript事件及通知等,通过复写onJsMessageShow方法来接管Web页面弹出Alert对话框的事件,示例代码如下:

  1. webview.setBrowserAgent(new BrowserAgent(this) {  
  2.             @Override  
  3.             public boolean onJsMessageShow(WebView webView, String url, String message, boolean isAlert, JsMessageResult result) {  
  4.                 LogUtil.info(TAG,"BrowserAgent onJsMessageShow : " + message);  
  5.                 if (isAlert) {  
  6.                     // 将Web页面的alert对话框改为ToastDialog方式提示  
  7.                     new ToastDialog(getApplicationContext()).setText(message).setAlignment(LayoutAlignment.CENTER).show();  
  8.                     // 对弹框进行确认处理  
  9.                     result.confirm();  
  10.                     return true;  
  11.                 } else {  
  12.                     return super.onJsMessageShow(webView, url, message, isAlert, result);  
  13.                 }  
  14.             }  
  15.         }); 

2.本地Web页面使用JavaScript调用App应用

在" text.html"中编写按钮,实现Web页面JavaScript对App应用的调用,示例代码如下:

  1. <body>  
  2.     ......  
  3. <button id="button" onclick="sendData()" style="background-color:#70DBDB;height:30px;">调用Java方法</button>  
  4. <script type="text/javascript">  
  5.   function sendData() {  
  6.     if (window.JsCallJava && window.JsCallJava.call) {  
  7.         // Web页面调用应用  
  8.         var rst = window.JsCallJava.call("这个是来自本地Web页面的消息");  
  9.     } else {  
  10.         alert('发送消息给WebviewSlice失败');  
  11.     }  
  12.   }  
  13. </script>  
  14. </body> 

在"slice/MainAbilitySlice.java"中实现APP应用对JavaScript发起的调用的响应,示例代码如下:

  1. private static final String JS_NAME = "JsCallJava";  
  2. webview.addJsCallback(JS_NAME, str -> {  
  3.   // 处理接收到的JavaScript发送来的消息,本教程通过ToastDialog提示确认收到Web页面发来的消息  
  4.   new ToastDialog(this).setText(str).setAlignment(LayoutAlignment.CENTER).show();  
  5.   // 返回给JavaScript  
  6.   return "Js Call Java Success";  
  7. }); 

 当" text.html"页面中的“调用Java方法”按钮被点击时,呈现效果如图3:

至此,我们通过一个Demo学习了如何使用WebView组件创建UI界面、Web页面加载方式、APP应用与Web页面间的通信及交互。当然以上只是基础操作,更多场景应用及创新需要开发者们的奇思妙想,期待你的脑洞大开~

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com 

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2012-12-26 12:41:14

Android开发WebView

2021-07-27 10:09:27

鸿蒙HarmonyOS应用

2010-08-04 15:37:31

Flex图表

2018-04-08 16:03:16

2010-08-04 14:28:01

Flex组件

2022-09-29 09:07:08

DataGrip数据仓库数据库

2013-05-09 14:30:37

华为任正非企业网络安全

2009-12-28 17:40:10

WPF TextBox

2011-07-21 14:57:34

jQuery Mobi

2010-09-06 14:24:28

ppp authent

2021-01-12 14:37:09

开发科学写作

2016-11-28 09:24:08

Python内存技巧

2021-04-27 15:30:54

鸿蒙HarmonyOS应用

2021-08-09 14:32:13

戴尔

2009-12-31 17:17:45

Silverlight

2021-01-12 15:19:23

Kubernetes

2010-06-03 17:27:36

Hadoop命令

2010-08-05 15:40:21

FlexBuilder

2017-01-04 15:22:57

TrimPath模板引擎
点赞
收藏

51CTO技术栈公众号