现代应用开发经常需要访问HTTP服务器。常用的Web编程框架包括:
它们虽然非常易用且流行,但目前在HarmonyOS上还无法使用。系统自带的HttpURLConnection,接口非常繁琐,加之多线程,会使程序变得十分臃肿。
ZZRHttp是一款可在HarmonyOS上使用的,轻量级Web编程框架。一方面它隐藏了网络访问的诸多细节,另一方面又提供了优雅的界面更新机制。
在.../entry/src/main/config.json文件的module中添加网络访问权限:
"reqPermissions": [ { "name": "ohos.permission.INTERNET" } ]
HarmonyOS默认采用https模式访问网络,如果所请求网址是http开头的,则需要在.../entry/src/main/config.json文件的deviceConfig中添加如下设置:
"default": { "network": { "cleartextTraffic": true } }
在.../entry/build.gradle文件的dependencies中添加ZZRHttp:
dependencies {
implementation 'com.zzrv5.zzrhttp:ZZRHttp:1.0.1'
}
点右上角“Sync Now”同步。
ZZRHttp.get(url, new ZZRCallBack.CallBackString() { @Override public void onFailure(int code, String errorMessage) { // HTTP访问失败,以下代码在主线程中执 // 行,可以更新UI,但不要执行阻塞操作 ... } @Override public void onResponse(String response) { // HTTP访问成功,以下代码在主线程中执 // 行,可以更新UI,但不要执行阻塞操作 ... } });
get( String url, ZZRCallBack callBack ); get( String url, Map<String, String> paramsMap, ZZRCallBack callBack ); get( String url, Map<String, String> paramsMap, Map<String, String> headerMap, ZZRCallBack callBack ); post( String url, ZZRCallBack callBack ); post( String url, Map<String, String> paramsMap, ZZRCallBack callBack ); post( String url, Map<String, String> paramsMap, Map<String, String> headerMap, ZZRCallBack callBack ); postJson( String url, String jsonStr, ZZRCallBack callBack ); postJson( String url, String jsonStr, Map<String, String> headerMap, ZZRCallBack callBack );
例程:HttpClient
...\HttpClient\entry\src\main\config.json
{ ... "deviceConfig": { "default": { "network": { "cleartextTraffic": true } } }, "module": { ... "reqPermissions": [ { "name": "ohos.permission.INTERNET" } ] } }
...\HttpClient\entry\build.gradle
...
dependencies {
...
implementation 'com.zzrv5.zzrhttp:ZZRHttp:1.0.1'
}
...
...\HttpClient\entry\src\main\resources\base\graphic\background_textfield.xml
<?xml version="1.0" encoding="UTF-8" ?> <shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle"> <solid ohos:color="#ffffff"/> <stroke ohos:width="1vp" ohos:color="#00a2e8"/> </shape>
...\HttpClient\entry\src\main\resources\base\graphic\background_button.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle"> <corners ohos:radius="100"/> <solid ohos:color="#00a2e8"/> </shape>
...\HttpClient\entry\src\main\resources\base\graphic\background_scrollview.xml
<?xml version="1.0" encoding="UTF-8" ?> <shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle"> <solid ohos:color="#cef0ff"/> <stroke ohos:width="1vp" ohos:color="#00a2e8"/> </shape>
...\HttpClient\entry\src\main\resources\base\graphic\background_text.xml
<?xml version="1.0" encoding="UTF-8" ?> <shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle"> <solid ohos:color="#ffd8da"/> <stroke ohos:width="1vp" ohos:color="#ff0000"/> </shape>
...\HttpClient\entry\src\main\resources\base\layout\ability_main.xml
<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:padding="20vp" ohos:orientation="vertical"> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="horizontal"> <TextField ohos:id="$+id:tf" ohos:height="match_content" ohos:width="match_parent" ohos:weight="1" ohos:padding="2vp" ohos:background_element="$graphic:background_textfield" ohos:hint="输入网址" ohos:text="https://www.baidu.com" ohos:text_size="20fp"/> <Button ohos:id="$+id:btn" ohos:height="match_content" ohos:width="match_content" ohos:left_padding="20vp" ohos:right_padding="20vp" ohos:top_padding="2vp" ohos:bottom_padding="4vp" ohos:left_margin="10vp" ohos:background_element="$graphic:background_button" ohos:text="Go" ohos:text_size="20fp" ohos:text_color="#ffffff" /> </DirectionalLayout> <ScrollView ohos:height="match_parent" ohos:weight="1" ohos:width="match_parent" ohos:padding="2vp" ohos:top_margin="10vp" ohos:background_element="$graphic:background_scrollview" ohos:rebound_effect="true"> <Text ohos:id="$+id:txtResponse" ohos:height="match_content" ohos:width="match_parent" ohos:multiple_lines="true" ohos:text_size="20fp" /> </ScrollView> <Text ohos:id="$+id:txtStatus" ohos:height="match_content" ohos:width="match_parent" ohos:padding="2vp" ohos:top_margin="10vp" ohos:background_element="$graphic:background_text" ohos:multiple_lines="true" ohos:text="就绪" ohos:text_size="20fp" ohos:text_color="#ff0000" /> </DirectionalLayout>
...\HttpClient\entry\src\main\java\com\minwei\httpclient\slice\MainAbilitySlice.java
public class MainAbilitySlice extends AbilitySlice { private TextField textField; private Button button; private Text txtResponse, txtStatus; @Override public void onStart(Intent intent) { ... textField = (TextField)findComponentById(ResourceTable.Id_tf); button = (Button)findComponentById(ResourceTable.Id_btn); txtResponse = (Text)findComponentById(ResourceTable.Id_txtResponse); txtStatus = (Text)findComponentById(ResourceTable.Id_txtStatus); button.setClickedListener(component -> { txtResponse.setText(""); txtStatus.setText("正在请求网络,请稍候..."); ZZRHttp.get(textField.getText(), new CallBackString() { @Override public void onFailure(int code, String errorMessage) { txtStatus.setText(errorMessage); } @Override public void onResponse(String response) { txtResponse.setText(response); txtStatus.setText("就绪"); } }); }); } ... }
运行效果如下图所示:
聚合数据(https://www.juhe.cn)为网络开发者提供了丰富的远程API测试接口。无需自行编写服务器程序,即可验证测试基于HarmonyOS的各种网络应用。
常用JSON解析工具:Jackson、gson。
中央仓库(https://mvnrepository.com)
JSON Libraries
Jackson Databind
2.12.4
Gradle (Short):
implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.4'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.12.4'
implementation 'com.fasterxml.jackson.core:jackson-core:2.12.4'
例程:Almanac
...\Almanac\entry\src\main\config.json
{ ... "deviceConfig": { "default": { "network": { "cleartextTraffic": true } } }, "module": { ... "reqPermissions": [ { "name": "ohos.permission.INTERNET" } ] } }
...\Almanac\entry\build.gradle
...
dependencies {
...
implementation 'com.zzrv5.zzrhttp:ZZRHttp:1.0.1'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.4'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.12.4'
implementation 'com.fasterxml.jackson.core:jackson-core:2.12.4'
}
...
...\Almanac\entry\src\main\resources\base\layout\ability_main.xml
<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:padding="20vp" ohos:alignment="horizontal_center" ohos:orientation="vertical"> <Text ohos:height="match_content" ohos:width="match_content" ohos:text="今日黄历" ohos:text_size="24fp" /> <Text ohos:height="2vp" ohos:width="match_parent" ohos:top_margin="10vp" ohos:bottom_margin="5vp" ohos:background_element="#808080" /> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="horizontal"> <Text ohos:height="match_content" ohos:width="100vp" ohos:text="阳历" ohos:text_size="18fp" ohos:text_color="#00a2e8" ohos:text_alignment="horizontal_center" /> <Text ohos:id="$+id:txtYangli" ohos:height="match_content" ohos:width="match_parent" ohos:multiple_lines="true" ohos:text_size="18fp" /> </DirectionalLayout> <Text ohos:height="1vp" ohos:width="match_parent" ohos:top_margin="5vp" ohos:bottom_margin="5vp" ohos:background_element="#808080" /> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="horizontal"> <Text ohos:height="match_content" ohos:width="100vp" ohos:text="阴历" ohos:text_size="18fp" ohos:text_color="#00a2e8" ohos:text_alignment="horizontal_center" /> <Text ohos:id="$+id:txtYinli" ohos:height="match_content" ohos:width="match_parent" ohos:multiple_lines="true" ohos:text_size="18fp" /> </DirectionalLayout> <Text ohos:height="1vp" ohos:width="match_parent" ohos:top_margin="5vp" ohos:bottom_margin="5vp" ohos:background_element="#808080" /> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="horizontal"> <Text ohos:height="match_content" ohos:width="100vp" ohos:text="五行" ohos:text_size="18fp" ohos:text_color="#00a2e8" ohos:text_alignment="horizontal_center" /> <Text ohos:id="$+id:txtWuxing" ohos:height="match_content" ohos:width="match_parent" ohos:multiple_lines="true" ohos:text_size="18fp" /> </DirectionalLayout> <Text ohos:height="1vp" ohos:width="match_parent" ohos:top_margin="5vp" ohos:bottom_margin="5vp" ohos:background_element="#808080" /> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="horizontal"> <Text ohos:height="match_content" ohos:width="100vp" ohos:text="冲煞" ohos:text_size="18fp" ohos:text_color="#00a2e8" ohos:text_alignment="horizontal_center" /> <Text ohos:id="$+id:txtChongsha" ohos:height="match_content" ohos:width="match_parent" ohos:multiple_lines="true" ohos:text_size="18fp" /> </DirectionalLayout> <Text ohos:height="1vp" ohos:width="match_parent" ohos:top_margin="5vp" ohos:bottom_margin="5vp" ohos:background_element="#808080" /> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="horizontal"> <Text ohos:height="match_content" ohos:width="100vp" ohos:text="彭祖百忌" ohos:text_size="18fp" ohos:text_color="#00a2e8" ohos:text_alignment="horizontal_center" /> <Text ohos:id="$+id:txtBaiji" ohos:height="match_content" ohos:width="match_parent" ohos:multiple_lines="true" ohos:text_size="18fp" /> </DirectionalLayout> <Text ohos:height="1vp" ohos:width="match_parent" ohos:top_margin="5vp" ohos:bottom_margin="5vp" ohos:background_element="#808080" /> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="horizontal"> <Text ohos:height="match_content" ohos:width="100vp" ohos:text="吉神宜趋" ohos:text_size="18fp" ohos:text_color="#00a2e8" ohos:text_alignment="horizontal_center" /> <Text ohos:id="$+id:txtJishen" ohos:height="match_content" ohos:width="match_parent" ohos:multiple_lines="true" ohos:text_size="18fp" /> </DirectionalLayout> <Text ohos:height="1vp" ohos:width="match_parent" ohos:top_margin="5vp" ohos:bottom_margin="5vp" ohos:background_element="#808080" /> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="horizontal"> <Text ohos:height="match_content" ohos:width="100vp" ohos:text="宜" ohos:text_size="18fp" ohos:text_color="#00a2e8" ohos:text_alignment="horizontal_center" /> <Text ohos:id="$+id:txtYi" ohos:height="match_content" ohos:width="match_parent" ohos:multiple_lines="true" ohos:text_size="18fp" /> </DirectionalLayout> <Text ohos:height="1vp" ohos:width="match_parent" ohos:top_margin="5vp" ohos:bottom_margin="5vp" ohos:background_element="#808080" /> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="horizontal"> <Text ohos:height="match_content" ohos:width="100vp" ohos:text="凶神宜忌" ohos:text_size="18fp" ohos:text_color="#00a2e8" ohos:text_alignment="horizontal_center" /> <Text ohos:id="$+id:txtXiongshen" ohos:height="match_content" ohos:width="match_parent" ohos:multiple_lines="true" ohos:text_size="18fp" /> </DirectionalLayout> <Text ohos:height="1vp" ohos:width="match_parent" ohos:top_margin="5vp" ohos:bottom_margin="5vp" ohos:background_element="#808080" /> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="horizontal"> <Text ohos:height="match_content" ohos:width="100vp" ohos:text="忌" ohos:text_size="18fp" ohos:text_color="#00a2e8" ohos:text_alignment="horizontal_center" /> <Text ohos:id="$+id:txtJi" ohos:height="match_content" ohos:width="match_parent" ohos:multiple_lines="true" ohos:text_size="18fp" /> </DirectionalLayout> <Text ohos:height="2vp" ohos:width="match_parent" ohos:top_margin="5vp" ohos:bottom_margin="10vp" ohos:background_element="#808080" /> <ScrollView ohos:height="match_parent" ohos:width="match_parent" ohos:rebound_effect="true"> <Text ohos:id="$+id:txtStatus" ohos:height="match_content" ohos:width="match_parent" ohos:multiple_lines="true" ohos:text_size="15fp" ohos:text_color="#ff0000" /> </ScrollView> </DirectionalLayout>
...\Almanac\entry\src\main\java\com\minwei\almanac\common\Almanac.java
public class Almanac { private String reason; private Result result; private int error_code; public String getReason() { return reason; } public void setReason(String reason) { this.reason = reason; } public Result getResult() { return result; } public void setResult(Result result) { this.result = result; } public int getError_code() { return error_code; } public void setError_code(int error_code) { this.error_code = error_code; } public static class Result { private int id; private String yangli; private String yinli; private String wuxing; private String chongsha; private String baiji; private String jishen; private String yi; private String xiongshen; private String ji; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getYangli() { return yangli; } public void setYangli(String yangli) { this.yangli = yangli; } public String getYinli() { return yinli; } public void setYinli(String yinli) { this.yinli = yinli; } public String getWuxing() { return wuxing; } public void setWuxing(String wuxing) { this.wuxing = wuxing; } public String getChongsha() { return chongsha; } public void setChongsha(String chongsha) { this.chongsha = chongsha; } public String getBaiji() { return baiji; } public void setBaiji(String baiji) { this.baiji = baiji; } public String getJishen() { return jishen; } public void setJishen(String jishen) { this.jishen = jishen; } public String getYi() { return yi; } public void setYi(String yi) { this.yi = yi; } public String getXiongshen() { return xiongshen; } public void setXiongshen(String xiongshen) { this.xiongshen = xiongshen; } public String getJi() { return ji; } public void setJi(String ji) { this.ji = ji; } } }
...\Almanac\entry\src\main\java\com\minwei\almanac\slice\MainAbilitySlice.java
public class MainAbilitySlice extends AbilitySlice { private Text txtYangli, txtYinli, txtWuxing, txtChongsha, txtBaiji, txtJishen, txtYi, txtXiongshen, txtJi, txtStatus; @Override public void onStart(Intent intent) { ... txtYangli = (Text)findComponentById(ResourceTable.Id_txtYangli); txtYinli = (Text)findComponentById(ResourceTable.Id_txtYinli); txtWuxing = (Text)findComponentById(ResourceTable.Id_txtWuxing); txtChongsha = (Text)findComponentById(ResourceTable.Id_txtChongsha); txtBaiji = (Text)findComponentById(ResourceTable.Id_txtBaiji); txtJishen = (Text)findComponentById(ResourceTable.Id_txtJishen); txtYi = (Text)findComponentById(ResourceTable.Id_txtYi); txtXiongshen = (Text)findComponentById(ResourceTable.Id_txtXiongshen); txtJi = (Text)findComponentById(ResourceTable.Id_txtJi); txtStatus = (Text)findComponentById(ResourceTable.Id_txtStatus); txtStatus.setText("正在请求网络,请稍候..."); String url = "http://v.juhe.cn/laohuangli/d"; Date time = Calendar.getInstance().getTime(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); String date = formatter.format(time); String key = "22f82c0c3cdd7aeb4e02e45cec27f419"; url += "?date=" + date + "&key=" + key; ZZRHttp.get(url, new CallBackString() { @Override public void onFailure(int code, String errorMessage) { txtStatus.setText(errorMessage); } @Override public void onResponse(String response) { txtStatus.setText(""); try { Almanac almanac = new ObjectMapper() .readValue(response, Almanac.class); if (almanac.getError_code() != 0) txtStatus.setText(almanac.getReason()); else { Almanac.Result result = almanac.getResult(); txtYangli.setText(new SimpleDateFormat( "yyyy年M月d日").format(formatter.parse( result.getYangli(), new ParsePosition(0)))); txtYinli.setText(result.getYinli()); txtWuxing.setText(result.getWuxing() .replaceAll(" ", ",")); txtChongsha.setText(result.getChongsha()); txtBaiji.setText(result.getBaiji() .replaceAll(" ", ",")); txtJishen.setText(result.getJishen() .replaceAll(" ", "、")); txtYi.setText(result.getYi() .replaceAll(" ", "、")); txtXiongshen.setText(result.getXiongshen() .replaceAll(" ", "、")); txtJi.setText(result.getJi() .replaceAll(" ", "、")); } } catch (JsonProcessingException exception) { txtStatus.setText(exception.toString()); } } }); } ... }
运行效果如下图所示:
在实际的应用开发中,经常需要在应用内部打开特定的网页,而不是用系统自带的浏览器打开网页。甚至很多公司的应用本身就只是打开一个特定的网页,比如掌阅等。这样开发的好处是,只需要编写极少量的代码就可以完成交互。
HarmonyOS的WebView组件为开发者提供了在应用中内嵌Web浏览器的功能。
在/entry/src/main/config.json文件的module中添加:
"reqPermissions": [ { "name": "ohos.permission.INTERNET" } ]
在/entry/src/main/config.json文件的deviceConfig中添加:
"default": { "network": { "cleartextTraffic": true } }
<ohos.agp.components.webengine.WebView
ohos:id="$+id:wv"
ohos:height="match_parent"
ohos:width="match_parent"/>
webView.setWebAgent(new WebAgent() { @Override public boolean isNeedLoadUrl(WebView webView, ResourceRequest resourceRequest) { return super.isNeedLoadUrl(webView, resourceRequest); } });
webView.load(textField.getText());
例程:Basic
...\Basic\entry\src\main\config.json
{ ... "deviceConfig": { "default": { "network": { "cleartextTraffic": true } } }, "module": { ... "reqPermissions": [ { "name": "ohos.permission.INTERNET" } ] } }
...\Basic\entry\src\main\resources\base\graphic\background_textfield.xml
<?xml version="1.0" encoding="UTF-8" ?> <shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle"> <solid ohos:color="#ffffff"/> <stroke ohos:width="1vp" ohos:color="#00a2e8"/> </shape>
...\Basic\entry\src\main\resources\base\graphic\background_button.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle"> <corners ohos:radius="100"/> <solid ohos:color="#00a2e8"/> </shape>
...\Basic\entry\src\main\resources\base\graphic\background_directionallayout.xml
<?xml version="1.0" encoding="UTF-8" ?> <shape xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:shape="rectangle"> <stroke ohos:width="1vp" ohos:color="#00a2e8"/> </shape>
...\Basic\entry\src\main\resources\base\layout\ability_main.xml
<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:padding="20vp" ohos:orientation="vertical"> <DirectionalLayout ohos:height="match_content" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="horizontal"> <TextField ohos:id="$+id:tf" ohos:height="match_content" ohos:width="match_parent" ohos:weight="1" ohos:padding="2vp" ohos:background_element="$graphic:background_textfield" ohos:hint="输入网址" ohos:text="https://www.baidu.com" ohos:text_size="20fp"/> <Button ohos:id="$+id:btn" ohos:height="match_content" ohos:width="match_content" ohos:left_padding="20vp" ohos:right_padding="20vp" ohos:top_padding="2vp" ohos:bottom_padding="4vp" ohos:left_margin="10vp" ohos:background_element="$graphic:background_button" ohos:text="Go" ohos:text_size="20fp" ohos:text_color="#ffffff" /> </DirectionalLayout> <DirectionalLayout ohos:height="match_parent" ohos:width="match_parent" ohos:padding="2vp" ohos:top_margin="10vp" ohos:background_element="$graphic:background_directionallayout"> <ohos.agp.components.webengine.WebView ohos:id="$+id:wv" ohos:height="match_parent" ohos:width="match_parent"/> </DirectionalLayout> </DirectionalLayout>
...\Basic\entry\src\main\java\com\minwei\basic\slice\MainAbilitySlice.java
public class MainAbilitySlice extends AbilitySlice { private TextField textField; private Button button; private WebView webView; @Override public void onStart(Intent intent) { ... textField = (TextField)findComponentById(ResourceTable.Id_tf); button = (Button)findComponentById(ResourceTable.Id_btn); webView = (WebView)findComponentById(ResourceTable.Id_wv); button.setClickedListener(component -> { webView.setWebAgent(new WebAgent() { @Override public boolean isNeedLoadUrl(WebView webView, ResourceRequest resourceRequest) { return super.isNeedLoadUrl(webView, resourceRequest); } }); webView.load(textField.getText()); }); } ... }
运行效果如下图所示:
本地页面放在:
.../entry/src/main/resources/rawfile/local.html
读取页面内容:
webView.setWebAgent(new WebAgent() { @Override public ResourceResponse processResourceRequest( WebView webView, ResourceRequest request) { Uri uri = request.getRequestUrl(); if (!uri.getDecodedAuthority().equals("local")) return super.processResourceRequest( webView, request); String path = uri.getDecodedPath(); if (TextTool.isNullOrEmpty(path)) return super.processResourceRequest( webView, request); if (path.startsWith("/rawfile/")) { path = "entry/resources/rawfile/" + path.replace("/rawfile/", ""); String mimeType = URLConnection .guessContentTypeFromName(path); try { Resource data = getResourceManager() .getRawFileEntry(path).openRawFile(); return new ResourceResponse( mimeType, data, null); } catch (IOException exception) { return super.processResourceRequest( webView, request); } } else if (path.startsWith("/file/")) { path = getContext().getFilesDir() + path.replace("/file/", "/"); String mimeType = URLConnection .guessContentTypeFromName(path); try { InputStream data = new FileInputStream( new File(path)); return new ResourceResponse( mimeType, data, null); } catch (FileNotFoundException exception) { return super.processResourceRequest( webView, request); } } return super.processResourceRequest(webView, request); } });
加载本地页面:
webView.load("https://local/rawfile/local.html");
webView.getWebConfig().setJavaScriptPermit(true);
例程:Advanced
...\Advanced\entry\src\main\resources\rawfile\local.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>本地页面</title> <script type="text/javascript"> function onClick() { var result = JsCallbackToApp.call("页面传递给应用的数据"); } function add(a, b) { return a + b; } </script> </head> <body> <center> <input type="button" value="页面向应用传递数据" onclick="onClick()" /> </center> </body> </html>
...\Advanced\entry\src\main\resources\base\layout\ability_main.xml
<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="vertical"> <ohos.agp.components.webengine.WebView ohos:id="$+id:wv" ohos:height="32vp" ohos:width="match_content"/> <Button ohos:id="$+id:btn" ohos:height="match_content" ohos:width="match_content" ohos:padding="$ohos:float:button_radius" ohos:top_margin="200vp" ohos:background_element="#ff7f27" ohos:text="应用向页面传递数据" ohos:text_size="20fp" ohos:text_color="#ffffff" /> </DirectionalLayout>
...\Advanced\entry\src\main\java\com\minwei\advanced\slice\MainAbilitySlice.java
public class MainAbilitySlice extends AbilitySlice { private WebView webView; private Button button; @Override public void onStart(Intent intent) { ... webView = (WebView)findComponentById(ResourceTable.Id_wv); button = (Button)findComponentById(ResourceTable.Id_btn); webView.setWebAgent(new WebAgent() { @Override public boolean isNeedLoadUrl(WebView webView, ResourceRequest resourceRequest) { return super.isNeedLoadUrl(webView, resourceRequest); } @Override public ResourceResponse processResourceRequest( WebView webView, ResourceRequest request) { Uri uri = request.getRequestUrl(); if (!uri.getDecodedAuthority().equals("local")) return super.processResourceRequest( webView, request); String path = uri.getDecodedPath(); if (TextTool.isNullOrEmpty(path)) return super.processResourceRequest( webView, request); if (path.startsWith("/rawfile/")) { path = "entry/resources/rawfile/" + path.replace("/rawfile/", ""); String mimeType = URLConnection .guessContentTypeFromName(path); try { Resource data = getResourceManager() .getRawFileEntry(path).openRawFile(); return new ResourceResponse( mimeType, data, null); } catch (IOException exception) { return super.processResourceRequest( webView, request); } } else if (path.startsWith("/file/")) { path = getFilesDir() + path.replace("/file/", "/"); String mimeType = URLConnection .guessContentTypeFromName(path); try { InputStream data = new FileInputStream( new File(path)); return new ResourceResponse( mimeType, data, null); } catch (FileNotFoundException exception) { return super.processResourceRequest( webView, request); } } return super.processResourceRequest(webView, request); } }); webView.getWebConfig().setJavaScriptPermit(true); webView.addJsCallback("JsCallbackToApp", new JsCallback() { @Override public String onCallback(String msg) { new ToastDialog(getContext()) .setText(msg) .setAlignment(LayoutAlignment.CENTER) .show(); return "RETURN_FROM_APP"; } }); button.setClickedListener(component -> { webView.executeJs("javascript:add(123,456)", new AsyncCallback<String>() { @Override public void onReceive(String msg) { new ToastDialog(getContext()) .setText("123+456=" + msg) .setAlignment(LayoutAlignment.CENTER) .show(); } }); }); webView.load("https://local/rawfile/local.html"); } ... }
运行效果如下图所示: