華為云享專家,InfoQ簽約作者,阿里云專家博主,51CTO博客首席體驗官,開源項目GVA成員之一,專注于大前端技術的分享,包括Flutter,小程序,安卓,VUE,JavaScript。
日常我們在開發項目時,為了項目快速的開發和迭代,難免會用到H5頁面。使用鴻蒙進行項目開發時,也一樣免不了要加載H5頁面,在移動開發中打開H5頁面需要使用WebView組件。同時,為了和H5頁面進行數據交換,有時候還需要借助JSBridge來實現客戶端與H5之間的通訊。
那么鴻蒙之中用到的技術是什么呢?WebView
在此之前,先看一個報錯
App Launch: The Huawei Lite Simulator supports only Lite projects.
這是什么原因呢,其實簡單,就是你沒有登陸
所以解決這個的問題就是你重新登錄就好了。
漢化(V3.0 Beta2(2021-12-31)版本以上支持)
還有一個問題可能就是目前編輯器大家看著不太習慣,需要漢化一下,那么如何漢化呢,結合Androidstudio的經驗,分為如下幾步
第一步點擊File-setting
第二步plugins里面選擇如圖所示的插件,并安裝。
第三步,重啟,漢化完成
第一步創建項目
點擊next
第二步等依賴安裝安裝完成
第三步打開模擬器
點擊登錄,打開瀏覽器授權
選擇p40
啟動模擬器
第五步開始正文
接下來開始正文。
應用預覽:
點擊"打開網址"按鈕會加載上方網址的Web頁面,通過后退"和"前進"按鈕實現Web頁面間的導航。
點擊"加載本地網頁"按鈕加載本地Web頁面,點擊"發送消息給本地html"或者Web頁面中的"調用Java方法"按鈕,實現應用與Web頁面間的交互。
這里是http訪問方式,鴻蒙的默認是https訪問模式,如果您的請求網址是http開頭的,可以繼續查看后面的教程。
1. 增加一個WebView組件
步驟 1 - 在"resources/base/layout/ability_main.xml"文件中創建WebView,示例代碼如下:
ohos:id
=
"$+id:webview"
ohos:height
=
"match_parent"
ohos:width
=
"match_parent"
>
步驟 2 - 在"slice/MainAbilitySlice.java"文件中通過如下方式獲取WebView對象,示例代碼如下:
WebView webview = (WebView) findComponentById(ResourceTable.Id_webview);
2. 通過WebView加載Web頁面
WebView加載頁面分為加載Web頁面和加載本地Web頁面兩種情況,接下來我們將分別進行介紹。
1.WebView加載網絡Web頁面
跟Android類似,要訪問網絡,我們首先要配置網絡訪問權限,在config.json的"module"節點最后,添加上網絡權限代碼
module": {
......
"reqPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
}
2 設置訪問模式
鴻蒙的默認是https訪問模式,如果您的請求網址是http開頭的,請在config.json文件中的deviceConfig下,添加如下設置
"deviceConfig": {
"default": {
"network": {
"cleartextTraffic": true
}
}
},
在"slice/MainAbilitySlice.java"文件中通過webview.load(String url)方法訪問具體的Web頁面,通過WebConfig類對WebView組件的行為進行配置,示例代碼如下:
WebConfig webConfig = webview.getWebConfig();
// WebView加載URL,其中urlTextField為輸入URL的TextField組件
webview.load(urlTextField.getText());
在Web頁面進行鏈接跳轉時,WebView默認會打開目標網址,通過WebAgent對象可以定制該行為,示例代碼如下:
webview
.
setWebAgent
(
new
WebAgent
() {
@Override
public
boolean
isNeedLoadUrl
(
WebView
webView
,
ResourceRequest
request
) {
if
(
request
==
null
||
request
.
getRequestUrl
()
==
null
) {
LogUtil
.
info
(
TAG
,
"WebAgent isNeedLoadUrl:request is 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
);
}
}
});
除此之外,WebAgent對象還提供了相關的回調函數以觀測頁面狀態的變更,如onLoadingPage、onPageLoaded、onError等方法。WebView提供Navigator類進行歷史記錄的瀏覽和處理,通過getNavigator()方法獲取該類的對象,使用canGoBack()或canGoForward()方法檢查是否可以向后或向前瀏覽,使用goBack()或goForward()方法向后或向前瀏覽,示例代碼如下:
Navigator navigator = webView.getNavigator();
if (navigator.canGoBack()) {
navigator.goBack();
}
if (navigator.canGoForward()) {
navigator.goForward();
}
3.WebView加載本地Web頁面
將本地的HTML文件放在"resources/rawfile/"目錄下,在本教程中命名為test.html。在HarmonyOS系統中,WebView要訪問本地Web文件,需要通過DataAbility的方式進行訪問,DataAbility的具體使用方法可以參考開發
DataAbility,關于DataAbility的相關知識,后面也會繼續展示,誰讓他是最重要的內容呢。
在"entry/src/main/config.json"中完成DataAbility的聲明,示例代碼如下:
module": {
......
"abilities": [
{
"name": "com.huawei.codelab.DataAbility",
"type": "data",
"uri": "dataability://com.example.harmonyosdemo.DataAbility"
}
]
}
另外需要實現一個DataAbility,通過實現openRawFile(Uri uri, String mode)方法,完成WebView對本地Web頁面的訪問,示例代碼如下:
public class DataAbility extends Ability { ... @Override public RawFileDescriptor openRawFile(Uri uri, String mode) throws FileNotFoundException { if (uri == null) {; return super.openRawFile(uri, mode); } String path = uri.getEncodedPath(); int splitIndex = path.indexOf('/', 1); 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; } }
在"slice/MainAbilitySlice.java"中聲明需要訪問的文件路徑,通過webview.load(String url)方法加載本地Web頁面,可以通過WebConfig類的對象對WebView訪問DataAbility的能力進行配置,示例代碼如下:
private static final String URL_LOCAL = "dataability://com.huawei.codelab.DataAbility/resources/rawfile/test.html"; // 配置是否支持訪問DataAbility資源,默認為true webConfig.setDataAbilityPermit(true); webview.load(URL_LOCAL);
4. 實現應用與WebView中的Web頁面間的通信
本教程以本地Web頁面"resources/rawfile/test.html"為例介紹如何實現應用與WebView中的Web頁面間交互。 首先需要對WebConfig進行配置,使能WebView與Web頁面JavaScript交互的能力,示例代碼如下:
// 配置是否支持JavaScript,默認值為false webConfig.setJavaScriptPermit(true);
1.應用調用Web頁面
在"resources/rawfile/test.html"中編寫callJS方法,待應用調用,示例代碼如下:
// 應用調用Web頁面 function callJS(message) { alert(message); }
在"slice/MainAbilitySlice.java"中實現應用對JavaScript的調用,示例代碼如下:
webview.executeJs("javascript:callJS('這是來自JavaSlice的消息')", msg -> { // 在這里處理Js的方法的返回值 });
我們可以通過setBrowserAgent方法設置自定義BrowserAgent對象,以觀測JavaScript事件及通知等,通過復寫onJsMessageShow方法來接管Web頁面彈出Alert對話框的事件,示例代碼如下:
webview.setBrowserAgent(new BrowserAgent(this) { @Override public boolean onJsMessageShow(WebView webView, String url, String message, boolean isAlert, JsMessageResult result) { LogUtil.info(TAG,"BrowserAgent onJsMessageShow : " + message); if (isAlert) { // 將Web頁面的alert對話框改為ToastDialog方式提示 new ToastDialog(getApplicationContext()).setText(message).setAlignment(LayoutAlignment.CENTER).show(); // 對彈框進行確認處理 result.confirm(); return true; } else { return super.onJsMessageShow(webView, url, message, isAlert, result); } } });
2.Web頁面使用JavaScript調用應用
在"resources/rawfile/test.html"中編寫按鈕,當按鈕被點擊時實現JavaScript對應用的調用,示例代碼如下:
調用Java方法 function sendData() { if (window.JsCallJava && window.JsCallJava.call) { // Web頁面調用應用 var rst = window.JsCallJava.call("這個是來自本地Web頁面的消息"); } else { alert('發送消息給WebviewSlice失敗'); } }
在"slice/MainAbilitySlice.java"中實現應用對JavaScript發起的調用的響應,示例代碼如下:
private static final String JS_NAME = "JsCallJava"; webview.addJsCallback(JS_NAME, str -> { // 處理接收到的JavaScript發送來的消息,本教程通過ToastDialog提示確認收到Web頁面發來的消息 new ToastDialog(this).setText(str).setAlignment(LayoutAlignment.CENTER).show(); // 返回給JavaScript return "Js Call Java Success"; });
總結
通過上面的完整代碼,我們已經完成了webbiew的基本使用
倉庫地址:https://github.com/ITmxs/hm_webview
感謝沒用的喵叔指出的問題
個人認為這兩句有點多余,默認處理http和https的邏輯應該就是return true,在父類里已經實現了。所以,這個方法直接改成這樣:
webview.setWebAgent(new WebAgent() { @Override public boolean isNeedLoadUrl(WebView webView, ResourceRequest request) { if (request == null || request.getRequestUrl() == null) { return false; } return super.isNeedLoadUrl(webView, request); } });
第二步刪除默認代碼
打開index.hml文件,里面有默認代碼如下:
山茶
第三步,開始學習
首先將圖片放到common文件夾下面的images里面,注意,我的圖片文件名是flutter.png,
從上面布局效果圖可以看到,界面主要由image組件和text組件組成,我們現在index.html中添加image組件和text組件,并添加對應的class,用于設置組件的顯示效果,代碼如下:
translate
rotate
rotateY
scale
opacity
第四步,為頁面設計樣式
在這個任務中,我們將一起為任務二中寫好的頁面添加樣式,上面所有的組件都定義了class屬性,它對應的樣式都定義在index.css中,有關css更多的知識可以參考css語法參考。 這部分定義了整個頁面中各個組件的樣式。在index.css中先添加如下代碼:
.container { background-color: #F8FCF5; flex-direction: column; justify-content: center; align-items: center; } .img { margin-top: 10px; height: 100px; width: 100px; animation-timing-function: ease; animation-duration: 2s; animation-delay: 0s; animation-fill-mode: forwards; animation-iteration-count: infinite; } .text { font-size: 20px; } .img-translate { animation-name: translateAnim; } .img-rotate { animation-name: rotateAnim; } .img-rotateY { animation-name: rotateYAnim; } .img-scale { animation-name: scaleAnim; } .img-mixes { animation-name: mixesAnim; } .img-opacity { animation-name: opacityAnim; } /*從-100px平移到100px*/ @keyframes translateAnim { from { transform: translate(-100px); } to { transform: translate(100px); } } /*從0°旋轉到360°*/ @keyframes rotateAnim { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /*沿Y軸旋轉,從0°旋轉到360°*/ @keyframes rotateYAnim { from { transform: rotateY(0deg); } to { transform: rotateY(360deg); } } /*從0倍縮放到1.2倍大小*/ @keyframes scaleAnim { from { transform: scale(0); } to { transform: scale(1.2); } } /*透明度從0變化到1*/ @keyframes opacityAnim { from { opacity: 0; } to { opacity: 1; } }
通過一個代碼示例,實現image組件的平移、縮放、旋轉和透明度變化動效。希望通過本教程,各位開發者可以對JS通用動畫樣式具有更深刻的認識。
在實現過程過也遇到一些問題,順便做個記錄
使用標簽引入的本地圖片無法加載
使用標簽引入本地圖片,但圖片無法加載的可能情況有三種:
沒有給圖片設置寬度和高度,需要在對應的“page”目錄下的 css 樣式文件中設置圖 片的寬高。
使用標簽的圖片不會自動縮放,圖片寬高超過組件的寬高會自動 截取。
圖片引入路徑錯誤。圖片引入的路徑必須是項目編譯后的靜態文件的路徑。 ? 在導入圖片或添加/刪除頁面后沒有重新編譯。
審核編輯:湯梓紅
-
華為
+關注
關注
216文章
34327瀏覽量
251223 -
鴻蒙系統
+關注
關注
183文章
2634瀏覽量
66226
發布評論請先 登錄
相關推薦
評論