4.7 [HarmonyOS Development] Component WebView
Author: Han Ru
Company: Procedural Coffee (Beijing) Technology Co., LTD
Columnist for Hung Mun Bus
WebView provides the ability to integrate Web pages into applications.
instructions
- Please use the real machine or emulator to run the WebView effect, the preview does not support WebView display.
- The WebView function is supported only on real devices with the preset WebView capability. For details, see the actual device support. Smart wearables do not support WebView.
1. How to use WebView
The WebView is derived from the generic Component and can be used just like a normal Component.
A:
Create a WebView in the XML file in the Layout directory.
<ohos.agp.components.webengine.WebView
ohos:id="$+id:webview"
ohos:height="match_parent"
ohos:width="match_parent">
</ohos.agp.components.webengine.WebView>
Copy the code
2. In the mainability.java file, load the Web page using the load method.
package com.example.hanruwebview.slice;
import com.example.hanruwebview.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.webengine.WebView;
public class MainAbilitySlice extends AbilitySlice {
private static final String EXAMPLE_URL="https://www.harmonybus.net/";
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
/ / load the WebView
WebView webView = (WebView) findComponentById(ResourceTable.Id_webview1);
webView.getWebConfig() .setJavaScriptPermit(true); // Add this line if the page needs JavaScript. How to use JavaScript is described in detail below
final String url = EXAMPLE_URL; // EXAMPLE_URL is defined by the developerwebView.load(url); }}Copy the code
Since we want to open the network and need network access, we need to authorize the network. Add the following authorization information to the config.json file:
"reqPermissions": [{"name": "ohos.permission.INTERNET"}]Copy the code
The structure is as follows:
Here we open the homepage of Hongmeng Bus:
Method 2:
Create a WebView in ComponentContainer.
We will create a new XML Layout file in the Layout directory: layout_webview_demo.xml. We do not need to add any control, just add the ID attribute in the root Layout.
<? 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:id="$+id:directionallayout1"
ohos:orientation="vertical">
</DirectionalLayout>
Copy the code
Then create a new AbilitySlice, SecondAbilitySlice. Java in the slice directory
package com.example.hanruwebview.slice;
import com.example.hanruwebview.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.webengine.WebView;
public class SecondAbilitySlice extends AbilitySlice {
private static final String EXAMPLE_URL="https://www.baidu.com/";
@Override
protected void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_layout_webview_demo);
// Method 2:
WebView webView = new WebView(getContext());
webView.setWidth(ComponentContainer.LayoutConfig.MATCH_PARENT);
webView.setHeight(ComponentContainer.LayoutConfig.MATCH_PARENT);
webView.getWebConfig() .setJavaScriptPermit(true); // Add this line if the page needs JavaScript. How to use JavaScript is described in detail belowDirectionalLayout directionalLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_directionallayout1); directionalLayout.addComponent(webView); }}Copy the code
2. Load the Web page.
final String url = EXAMPLE_URL; // EXAMPLE_URL is defined by the developer
webView.load(url);
Copy the code
Modify the entry to the program:
package com.example.hanruwebview;
import com.example.hanruwebview.slice.MainAbilitySlice;
import com.example.hanruwebview.slice.SecondAbilitySlice;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
public class MainAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
// super.setMainRoute(MainAbilitySlice.class.getName());
super.setMainRoute(SecondAbilitySlice.class.getName()); }}Copy the code
Take a look at the effect: the effect can not see, the platform audit can not pass.
Two, customized url loading behavior
When a Web page is linked, the WebView opens the target URL by default. You can customize this behavior in the following ways.
1. Customize WebAgent objects.
private class ExampleWebAgent extends WebAgent {
@Override
public boolean isNeedLoadUrl(WebView webView, ResourceRequest request) {
Uri uri = request.getRequestUrl();
if (EXAMPLE_URL.equals(uri.getDecodedHost())) {
// This is handled by the WebView by default
return false;
}
// Add developer custom logic
return super.isNeedLoadUrl(webView, request); }}Copy the code
2. Set custom WebAgent to WebView.
webView.setWebAgent(new ExampleWebAgent());
Copy the code
3. Browsing history
1. Get the Navigator object using the getNavigator method.
Navigator navigator = webView.getNavigator();
Copy the code
2, use canGoBack() or canGoForward() to check if you can browse backwards or forwards. Use goBack() or goForward() to browse backwards or forwards.
if (navigator.canGoBack()) {
navigator.goBack();
}
if (navigator.canGoForward()) {
navigator.goForward();
}
Copy the code
Use JavaScript
You can set up JavaScript calls between your application and your page in the following way.
Enable JavaScript via WebConfig.
webView.getWebConfig().setJavaScriptPermit(true);
Copy the code
2. Select the calling mode according to actual needs.
- Inject a callback object into the page content and invoke the object from within the page.
final String jsName = "JsCallbackToApp";
webview.addJsCallback(jsName, new JsCallback() {
@Override
public String onCallback(String msg) {
// Add custom processing
return "jsResult"; }});Copy the code
The injected object is called from within the page through JavaScript code.
function callToApp(a) {
if (window.JsCallbackToApp && window.JsCallbackToApp.call) {
var result = JsCallbackToApp.call("message from web"); }}Copy the code
- Calls JavaScript methods within the page from within the application.
webview.executeJs("javascript:callFuncInWeb()".new AsyncCallback<String>() {
@Override
public void onReceive(String msg) {
// Confirm the returned result here}});Copy the code
Observe the Web status
Use the setWebAgent method to set custom WebAgent objects to observe events such as page state changes:
webview.setWebAgent(new WebAgent() {
@Override
public void onLoadingPage(WebView webView, String url, PixelMap favicon) {
super.onLoadingPage(webView, url, favicon);
// Customizable processing when the page starts loading
}
@Override
public void onPageLoaded(WebView webView, String url) {
super.onPageLoaded(webView, url);
// Customizable processing after page loading
}
@Override
public void onLoadingContent(WebView webView, String url) {
super.onLoadingContent(webView, url);
// Custom processing when loading resources
}
@Override
public void onError(WebView webView, ResourceRequest request, ResourceError error) {
super.onError(webView, request, error);
// Custom processing when an error occurs}});Copy the code
6. Observe and browse events
Set a custom BrowserAgent object with the setBrowserAgent method to observe JavaScript events, notifications, and more:
webview.setBrowserAgent(new BrowserAgent(this) {
@Override
public void onTitleUpdated(WebView webView, String title) {
super.onTitleUpdated(webView, title);
// Customizable handling of title changes
}
@Override
public void onProgressUpdated(WebView webView, int newProgress) {
super.onProgressUpdated(webView, newProgress);
// Customizable processing when loading progress changes}});Copy the code
Load resource files or local files
For security reasons, the WebView does not support directly loading resource files or local files through the File protocol. If the application needs to implement related services, see the following methods.
A:Through the processResourceRequest methodAccess to the file
Set a custom WebAgent object by setWebAgent method and override processResourceRequest method.
webview.setWebAgent(new WebAgent() {
@Override
public ResourceResponse processResourceRequest(WebView webView, ResourceRequest request) {
final String authority = "example.com";
final String rawFile = "/rawfile/";
final String local = "/local/";
Uri requestUri = request.getRequestUrl();
if (authority.equals(requestUri.getDecodedAuthority())) {
String path = requestUri.getDecodedPath();
if (TextTool.isNullOrEmpty(path)) {
return super.processResourceRequest(webView, request);
}
if (path.startsWith(rawFile)) {
// Access resource files according to custom rules
String rawFilePath = "entry/resources/rawfile/" + path.replace(rawFile, "");
String mimeType = URLConnection.guessContentTypeFromName(rawFilePath);
try {
Resource resource = getResourceManager().getRawFileEntry(rawFilePath).openRawFile();
ResourceResponse response = new ResourceResponse(mimeType, resource, null);
return response;
} catch (IOException e) {
HiLog.info(TAG, "open raw file failed"); }}if (path.startsWith(local)) {
// Access local files according to custom rules
String localFile = getContext().getFilesDir() + path.replace(local, "/");
HiLog.info(TAG, "open local file " + localFile);
File file = new File(localFile);
if(! file.exists()) { HiLog.info(TAG,"file not exists");
return super.processResourceRequest(webView, request);
}
String mimeType = URLConnection.guessContentTypeFromName(localFile);
try {
InputStream inputStream = new FileInputStream(file);
ResourceResponse response = new ResourceResponse(mimeType, inputStream, null);
return response;
} catch (IOException e) {
HiLog.info(TAG, "open local file failed"); }}}return super.processResourceRequest(webView, request); }});Copy the code
2. Load resource files or local files.
/ / load the resource files resources/rawfile/example. The HTML
webView.load("https://example.com/rawfile/example.html");
/ / load the local file/data/data/com. Example. Dataability/files/example. HTML
webView.load("https://example.com/local/example.html");
Copy the code
** Use Data Ability to access files
1. Create Data Ability.
public class ExampleDataAbility extends Ability {
private static final String PLACEHOLDER_RAW_FILE = "/rawfile/";
private static final String PLACEHOLDER_LOCAL_FILE = "/local/";
private static final String ENTRY_PATH_PREFIX = "entry/resources";
@Override
public RawFileDescriptor openRawFile(Uri uri, String mode) throws FileNotFoundException {
final int splitChar = '/';
if (uri == null) {
throw new FileNotFoundException("Invalid Uri");
}
// path will be like /com.example.dataability/rawfile/example.html
String path = uri.getEncodedPath();
final int splitIndex = path.indexOf(splitChar, 1);
if (splitIndex < 0) {
throw new FileNotFoundException("Invalid Uri " + uri);
}
String targetPath = path.substring(splitIndex);
if (targetPath.startsWith(PLACEHOLDER_RAW_FILE)) {
// Access resource files according to custom rules
try {
return getResourceManager().getRawFileEntry(ENTRY_PATH_PREFIX + targetPath).openRawFileDescriptor();
} catch (IOException e) {
throw new FileNotFoundException("Not found support raw file at "+ uri); }}else if (targetPath.startsWith(PLACEHOLDER_LOCAL_FILE)) {
// Access local files according to custom rules
File file = new File(getContext().getFilesDir(), targetPath.replace(PLACEHOLDER_LOCAL_FILE, ""));
if(! file.exists()) {throw new FileNotFoundException("Not found support local file at " + uri);
}
return getRawFileDescriptor(file, uri);
} else {
throw new FileNotFoundException("Not found support file at "+ uri); }}private RawFileDescriptor getRawFileDescriptor(File file, Uri uri) throws FileNotFoundException {
try {
final FileDescriptor fileDescriptor = new FileInputStream(file).getFD();
return new RawFileDescriptor() {
@Override
public FileDescriptor getFileDescriptor(a) {
return fileDescriptor;
}
@Override
public long getFileSize(a) {
return -1;
}
@Override
public long getStartPosition(a) {
return 0;
}
@Override
public void close(a) throws IOException {}}; }catch (IOException e) {
throw new FileNotFoundException("Not found support local file at "+ uri); }}}Copy the code
2. Register Data Ability in config.json.
{
"name": "com.example.webview.ExampleDataAbility"."type": "data"."uri": "dataability://com.example.dataability"."metaData": {
"customizeData": [{"name": "com.example.provider"."extra": "$profile:path"}}}]Copy the code
Add path.xml to the resources/base/profile directory:
<paths>
<root-path name="root" path="/" />
</paths>
Copy the code
3. Configure support for access to Data Ability resources.
webConfig.setDataAbilityPermit(true);
Copy the code
4. Load resource files or local files through dataAbility protocol.
/ / load the resource files resources/rawfile/example. The HTML
webView.load("dataability://com.example.dataability/rawfile/example.html");
/ / load the local file/data/data/com. Example. Dataability/files/example. HTML
webView.load("dataability://com.example.dataability/local/example.html");
Copy the code
More:
1. Community: Hongmeng Bus www.harmonybus.net/
2. Official account: HarmonyBus
3, technical exchange QQ group: 714518656
4. Video lesson: www.chengxuka.com