The WebView component can be used to integrate web pages into an app. WebView inherits from Component. It can be used as a common component.
This codelab illustrates how to integrate the WebView component into an app. By walking through this codelab, you can learn how to create a WebView component, load web pages, and implement interaction between the app and web pages.
For details about the capabilities of the WebView component, see WebView.
The procedure is as follows:
Step 1 - Create a WebView object in the resources/base/layout/ability_main.xml file. The sample code is as follows:
<ohos.agp.components.webengine.WebView
ohos:id="$+id:webview"
ohos:height="match_parent"
ohos:width="match_parent">
</WebView>
Step 2 - Obtain the WebView object in the slice/MainAbilitySlice.java file. The sample code is as follows:
WebView webview = (WebView) findComponentById(ResourceTable.Id_webview);
—-End
The WebView component can be used to load web pages and local HTML files.
module": {
......
"reqPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
}
In the slice/MainAbilitySlice.java file, use the webview.load(String url) method to access a specific web page and use the WebConfig class to configure the behavior of the WebView component. The sample code is as follows:
WebConfig webConfig = webview.getWebConfig();
// WebView loads the URL. urlTextField is the TextField component where you can input the URL.
webview.load(urlTextField.getText());
The WebView component opens the target URL by default when the URL is redirected. You can use the WebAgent object to customize this behavior. The sample code is as follows:
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);
}
}
});
In addition, the WebAgent object provides callbacks, such as onLoadingPage, onPageLoaded, and onError, to observe page status changes. The WebView component provides the Navigator class for browsing and processing historical records. You can use getNavigator() to obtain a Navigator object, use canGoBack() or canGoForward() to check whether there is a previous or next page to go to, and use goBack() or goForward() go to the previous or next page. The sample code is as follows:
nNavigator navigator = webView.getNavigator();
if (navigator.canGoBack()) {
navigator.goBack();
}
if (navigator.canGoForward()) {
navigator.goForward();
}
module": {
......
"abilities": [
{
"name": "com.huawei.codelab.DataAbility",
"type": "data",
"uri": "dataability://com.huawei.codelab.DataAbility"
}
]
}
You must implement a Data ability and call the openRawFile(Uri uri, String mode) method to enable the WebView component to access the local HTML file. The sample code is as follows:
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) {
// Handle the exception.
}
return rawFileDescriptor;
}
}
Declare the path of the file to access in the slice/MainAbilitySlice.java file, call webview.load(String url) to load the local HTML file, and use the WebConfig object to enable the WebView component to access the Data ability. The sample code is as follows:
private static final String URL_LOCAL = "dataability://com.huawei.codelab.DataAbility/resources/rawfile/test.html";
// Set whether to allow access to the Data ability. The default value is true.
webConfig.setDataAbilityPermit(true);
webview.load(URL_LOCAL);
This codelab uses the local HTML file resources/rawfile/test.html as an example to describe how to implement interaction between apps and web pages in WebView.
Configure the WebConfig object to enable the interaction between WebView and JavaScript on the web page. The sample code is as follows:
// Set whether to enable JavaScript in WebView. The default value is false.
webConfig.setJavaScriptPermit(true);
<script type="text/javascript">
// The app calls the web page.
function callJS(message) {
alert(message);
}
</script>
Implement the call to JavaScript in the slice/MainAbilitySlice.java file. The sample code is as follows:
webview.executeJs("javascript:callJS('This is a message from JavaSlice.')", msg -> {
// Process the return value of the JavaScript method.
});
You can use the setBrowserAgent method to set a custom BrowserAgent object to observe JavaScript events and notifications, and override the onJsMessageShow method to process the display of the Alert dialog box on the web page. The sample code is as follows:
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) {
// Enable the Alert dialog box on the web page to be displayed as a ToastDialog.
new ToastDialog(getApplicationContext()).setText(message).setAlignment(LayoutAlignment.CENTER).show();
// Confirm the operation in the dialog box.
result.confirm();
return true;
} else {
return super.onJsMessageShow(webView, url, message, isAlert, result);
}
}
});
<body>
......
<button id="button" onclick="sendData()" style="background-color:#70DBDB;height:30px;">Call Java Method</button>
<script type="text/javascript">
function sendData() {
if (window.JsCallJava && window.JsCallJava.call) {
// The web page calls the app.
var rst = window.JsCallJava.call("This is a message from the local HTML file.");
} else {
alert('Failed to send the message to WebviewSlice.');
}
}
</script>
</body>
In slice/MainAbilitySlice.java, implement the response to the call initiated by JavaScript. The sample code is as follows:
private static final String JS_NAME = "JsCallJava";
webview.addJsCallback(JS_NAME, str -> {
// Process the message received from JavaScript. This codelab uses a ToastDialog to prompt you to confirm that the message sent by the web page is received.
new ToastDialog(this).setText(str).setAlignment(LayoutAlignment.CENTER).show();
// Return a response to JavaScript.
return "Js Call Java Success";
});
Well done! You have successfully completed this codelab and learned how to use the WebView component.
The following uses a complete example to describe how to use the WebView component. In this example, you can load a manually entered web URL or a local HTML file. You can also go to the previous or next page and implement interaction between the app and web pages. The display effect is as follows:
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:orientation="vertical"
ohos:width="match_parent">
<TextField
ohos:id="$+id:textField"
ohos:height="30vp"
ohos:width="match_parent"
ohos:left_margin="5vp"
ohos:right_margin="5vp"
ohos:text_alignment="vertical_center"
ohos:text="https://www.huawei.com/cn/"
ohos:hint="Enter a URL."
ohos:basement="#000099"
ohos:text_size="20fp">
</TextField>
<DirectionalLayout
ohos:height="510vp"
ohos:width="match_parent"
ohos:top_margin="5vp"
ohos:background_element="$graphic:background_button"
ohos:orientation="horizontal">
<ohos.agp.components.webengine.WebView
ohos:margin="5vp"
ohos:height="500vp"
ohos:id="$+id:webview"
ohos:width="match_parent"/>
</DirectionalLayout>
<Button
ohos:id="$+id:loadUrl"
ohos:height="30vp"
ohos:left_margin="5vp"
ohos:right_margin="5vp"
ohos:top_margin="5vp"
ohos:text="Load URL"
ohos:background_element="$graphic:background_button"
ohos:text_size="20fp"
ohos:width="match_parent">
</Button>
<DirectionalLayout
ohos:height="30vp"
ohos:width="match_parent"
ohos:top_margin="5vp"
ohos:orientation="horizontal">
<Button
ohos:id="$+id:goback"
ohos:height="match_parent"
ohos:width="1"
ohos:left_margin="5vp"
ohos:right_margin="5vp"
ohos:weight="1"
ohos:text="Go Back"
ohos:background_element="$graphic:background_button"
ohos:text_size="20fp">
</Button>
<Button
ohos:id="$+id:forward"
ohos:height="match_parent"
ohos:width="1"
ohos:text="GO Forward"
ohos:right_margin="5vp"
ohos:left_margin="5vp"
ohos:weight="1"
ohos:background_element="$graphic:background_button"
ohos:text_size="20fp">
</Button>
</DirectionalLayout>
<Button
ohos:width="match_parent"
ohos:id="$+id:load_local_url"
ohos:height="30vp"
ohos:text="Load Local HTML"
ohos:left_margin="5vp"
ohos:top_margin="5vp"
ohos:right_margin="5vp"
ohos:background_element="$graphic:background_button"
ohos:text_size="20fp">
</Button>
<Button
ohos:id="$+id:callJS"
ohos:height="30vp"
ohos:width="match_parent"
ohos:left_margin="5vp"
ohos:top_margin="5vp"
ohos:right_margin="5vp"
ohos:text="Send Message to Local HTML"
ohos:background_element="$graphic:background_button"
ohos:text_size="20fp">
</Button>
</DirectionalLayout>
Add the background_button.xml file in the resources/base/graphic/ directory to define background attributes.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<corners
ohos:radius="6vp"/>
<solid
ohos:color="#e9e9e9"/>
</shape>
import com.huawei.codelab.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.Navigator;
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.huawei.codelab.DataAbility/resources/rawfile/test.html";
private static final String JS_NAME = "JsCallJava";
private WebView webview;
private TextField urlTextField;
private Navigator navigator;
@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);
urlTextField = (TextField) findComponentById(ResourceTable.Id_textField);
navigator = webview.getNavigator();
initButton();
configWebView();
}
private void configWebView() {
WebConfig webConfig = webview.getWebConfig();
// Specify whether to support JavaScript. The default value is 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);
}
}
});
// Configure the processing of messages received from JavaScript.
webview.addJsCallback(JS_NAME, str -> {
// Process the message received from JavaScript.
new ToastDialog(this).setText(str).setAlignment(LayoutAlignment.CENTER).show();
// Return a response to JavaScript.
return "Js Call Java Success";
});
}
private void initButton() {
initLoadUrlButton();
initGoBackButton();
initGoForwardButton();
initLoadLocalUrlButton();
initCallJsButton();
}
private void initCallJsButton() {
Button callJs = (Button) findComponentById(ResourceTable.Id_callJS);
callJs.setClickedListener(component -> {
webview.executeJs("javascript:callJS('This is a message from JavaSlice.')", msg -> {
// Process the return value of the JavaScript method that is called by Java.
});
});
}
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());
});
}
private void initGoBackButton() {
Button goBackButton = (Button) findComponentById(ResourceTable.Id_goback);
goBackButton.setClickedListener(component -> {
if (navigator.canGoBack()) {
navigator.goBack();
}
});
}
private void initGoForwardButton() {
Button goForwardButton = (Button) findComponentById(ResourceTable.Id_forward);
goForwardButton.setClickedListener(component -> {
if (navigator.canGoForward()) {
navigator.goForward();
}
});
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
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) {
// Handle the exception.
}
return rawFileDescriptor;
}
}
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<title>Local HTML</title>
<body onload="hello">
<br>
<h1 id="helloName">This is a local HTML page.</h1>
<br>
<button id="button" onclick="sendData()" style="background-color:#70DBDB;height:30px;">Call Java Method</button>
<script type="text/javascript">
// The app calls the web page.
function callJS(message) {
alert(message);
}
function sendData() {
if (window.JsCallJava && window.JsCallJava.call) {
// The web page calls the app.
var rst = window.JsCallJava.call("This is a message from the local HTML file.");
} else {
alert('Failed to send the message to WebviewSlice.');
}
}
</script>
</body>
</html>