鴻蒙學習筆記:利用鴻蒙JavaUI 框架的 WebView 加載在線網頁
theme: channing-cyan
「這是我參與2022首次更文挑戰的第39天,活動詳情查看:2022首次更文挑戰」
什麼是 Webview
其實現在很多應用 App 裏都內置了 Web 網頁,比如微信、淘寶。在 Android 中就是利用 WebView 這一組件實現。WebView 是一個基於 webkit 引擎、展現 web 頁面的控件。
鴻蒙也不例外,也通過 WebView 來提供應用中集成 Web 頁面的能力。
作用: - 顯示和渲染 Web 頁面 - 直接使用 HTML文件(網絡上或本地 resources 中)作佈局 - 可和 JavaScript 交互調用
WebView 支持對網絡頁面的訪問,比如我這裏就是讀取 HarmonyOS應用開發官網,讀者當然可以自己想訪問哪個網頁就訪問自己的網頁。
WebView 使用
如果我們要加載遠程網頁,就要增加對網絡的支持。在 config.json
中寫入如下代碼:
json
"module": {
"package": "com.yuzhou1su.webviewdemo",
"name": ".MyApplication",
"mainAbility": "com.yuzhou1su.webviewdemo.MainAbility",
"deviceType": [
"phone", "tv", "tablet"
],
"reqPermissions": [
{
"name": "ohos.permission.INTERNET" // 增加網絡權限
}
],
在 layout 的 ability_main.xml
中創建 WebView
在"slice/MainAbilitySlice.java"文件中通過 webview.load(String url) 方法訪問具體的Web 頁面,通過 WebConfig 類對 WebView 組件的行為進行配置,代碼如下:
```java package com.yuzhou1su.webviewdemo.slice;
import com.yuzhou1su.webviewdemo.ResourceTable; import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; import ohos.agp.components.Button; import ohos.agp.components.TextField; import ohos.agp.components.webengine.BrowserAgent; import ohos.agp.components.webengine.JsMessageResult; import ohos.agp.components.webengine.ResourceRequest; import ohos.agp.components.webengine.WebAgent; import ohos.agp.components.webengine.WebConfig; import ohos.agp.components.webengine.WebView; import ohos.agp.utils.LayoutAlignment; import ohos.agp.window.dialog.ToastDialog;
public class MainAbilitySlice extends AbilitySlice {
private static final String URL_LOCAL = "dataability://com.yuzhou1su.webviewdemo.DataAbility/resources/rawfile/BingDwenDwen.html";
private static final String JS_NAME = "JsCallJava";
private WebView webview;
private TextField urlTextField;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
initView();
}
private void initView() {
webview = (WebView) findComponentById(ResourceTable.Id_webview);
webview.getWebConfig().setDataAbilityPermit(true); //這個要加上,設置 webview 支持打開本地文件
urlTextField = (TextField) findComponentById(ResourceTable.Id_textField);
initButton();
configWebView();
}
private void configWebView() {
WebConfig webConfig = webview.getWebConfig();
// 是否支持Javascript,默認值false
webConfig.setJavaScriptPermit(true);
webview.setWebAgent(new WebAgent() {
@Override
public boolean isNeedLoadUrl(WebView webView, ResourceRequest request) {
if (request == null || request.getRequestUrl() == null) {
return false;
}
String url = request.getRequestUrl().toString();
if (url.startsWith("http:") || url.startsWith("https:")) {
webView.load(url);
return false;
} else {
return super.isNeedLoadUrl(webView, request);
}
}
});
webview.setBrowserAgent(new BrowserAgent(this) {
@Override
public boolean onJsMessageShow(WebView webView, String url, String message, boolean isAlert, JsMessageResult result) {
if (isAlert) {
new ToastDialog(getApplicationContext()).setText(message).setAlignment(LayoutAlignment.CENTER).show();
result.confirm();
return true;
} else {
return super.onJsMessageShow(webView, url, message, isAlert, result);
}
}
});
// 配置JS發來的消息處理
webview.addJsCallback(JS_NAME, str -> {
// 處理接收到的Js發送來的消息
new ToastDialog(this).setText(str).setAlignment(LayoutAlignment.CENTER).show();
// 返回給Js
return "Js Call Java Success";
});
}
private void initButton() {
initLoadUrlButton();
initLoadLocalUrlButton();
}
private void initLoadLocalUrlButton() {
Button loadLocalUrlButton = (Button) findComponentById(ResourceTable.Id_load_local_url);
loadLocalUrlButton.setClickedListener(component -> {
webview.load(URL_LOCAL);
});
}
private void initLoadUrlButton() {
Button loadUrlButton = (Button) findComponentById(ResourceTable.Id_loadUrl);
loadUrlButton.setClickedListener(component -> {
webview.load(urlTextField.getText());
});
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
```
在 background_ability_main.xml
寫入如下代碼:
```xml
在 background_button.xml
寫入如下代碼:
```xml
WebView 讀取本地頁面
將本地的 HTML 文件放在"resources/rawfile/"目錄下,在本教程中命名為 BingDwenDwen.html 。在 HarmonyOS 系統中,WebView 要訪問本地 Web 文件,需要通過DataAbility 的方式進行訪問,所以此處創建 DataAbility.java
文件,寫入如下代碼:
```java
package com.yuzhou1su.webviewdemo;
import java.io.FileNotFoundException; import java.io.IOException;
import ohos.aafwk.ability.Ability; import ohos.aafwk.content.Intent; import ohos.global.resource.RawFileDescriptor; import ohos.utils.net.Uri;
public class DataAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
}
@Override
public RawFileDescriptor openRawFile(Uri uri, String mode) throws FileNotFoundException {
if (uri == null) {
return super.openRawFile(uri, mode);
}
String path = uri.getEncodedPath();
final int splitIndex = path.indexOf('/', 1);
final String providerName = Uri.decode(path.substring(1, splitIndex));
String rawFilePath = Uri.decode(path.substring(splitIndex + 1));
RawFileDescriptor rawFileDescriptor = null;
try {
rawFileDescriptor = getResourceManager().getRawFileEntry(rawFilePath).openRawFileDescriptor();
} catch (IOException e) {
// 處理異常
}
return rawFileDescriptor;
}
}
```
然後在 "entry/src/main/config.json" 中完成 DataAbility 的聲明,代碼如下:
json
{
"name": "com.yuzhou1su.webviewdemo.DataAbility",
"type": "data",
"uri": "dataability://com.yuzhou1su.webviewdemo.DataAbility"
}
至此,整個 config.json
文件內容如下:
json
{
"app": {
"bundleName": "com.yuzhou1su.webviewdemo",
"vendor": "yuzhou1su",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"deviceConfig": {},
"module": {
"package": "com.yuzhou1su.webviewdemo",
"name": ".MyApplication",
"mainAbility": "com.yuzhou1su.webviewdemo.MainAbility",
"deviceType": [
"phone", "tv", "tablet"
],
"reqPermissions": [
{
"name": "ohos.permission.INTERNET"
}
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "entry",
"moduleType": "entry",
"installationFree": true
},
"abilities": [
{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
],
"orientation": "unspecified",
"name": "com.yuzhou1su.webviewdemo.MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "$string:entry_MainAbility",
"type": "page",
"launchType": "standard"
},
{
"name": "com.yuzhou1su.webviewdemo.DataAbility",
"type": "data",
"uri": "dataability://com.yuzhou1su.webviewdemo.DataAbility"
}
]
}
}
然後在 "slice/MainAbilitySlice.java" 中聲明需要訪問的文件路徑,通過webview.load(String url) 方法加載本地 Web 頁面,可以通過 WebConfig 類的對象對WebView 訪問 DataAbility 的能力進行配置,示例代碼如下: ```java private static final String URL_LOCAL = "dataability://com.yuzhou1su.webviewdemo.DataAbility/resources/rawfile/BingDwenDwen.html"; private static final String JS_NAME = "JsCallJava"; private WebView webview; private TextField urlTextField;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
initView();
}
```
代碼結構如下
然後運行一個 MataPad Pro,執行我們的代碼:
點擊打開在線網頁,就能看到鴻蒙開發官網:
總結
在 App 開發中,內嵌 WebView 始終佔有着一席之地。它能以較低的成本實現 Android 、iOS 和 Web 的複用。 -- 美團技術團隊
至此,我們通過 WebView 來訪問遠程網頁和本地 HTML 都成功了,但是這僅僅是很小的一個工作。
如果大家還想繼續研究 WebView,可以自己多多探索,如果大家看完我的文章,有興趣去做出一個 APP 內置瀏覽器功能,那我的目的也就達到了。
希望更多小夥伴加入鴻蒙開發的隊伍,下一篇文章,我們再見!
參考資料: - 官方WebView案例
- 一文帶你瞭解 Python 中的繼承知識點
- 如何使用 HTML 和 CSS 寫一個登錄界面
- 代碼之外:寫作是倒逼成長的最佳方式
- Redis 的快速介紹及其基本數據類型和操作
- 經久不衰的設計定律就是——不要讓我思考的設計
- 一文了解 Python 中的裝飾器
- 聊聊 Go 語言與雲原生技術
- Go Web 編程入門:驗證器
- Golang 的藝術、哲學和科學
- Django API 開發:視圖設置和路由
- Web 編程入門:什麼是Web API?
- Python 實現設計模式之工廠模式
- 好開心我進入了面試環節,那麼我該如何自我介紹?
- 鴻蒙學習筆記:利用鴻蒙JavaUI 框架的 WebView 加載在線網頁
- Go 語言入門很簡單:讀寫鎖