HarmonyOS - JavaUI 框架之使用WebView加载本地H5页面 原创 精华

中软小助手
发布于 2022-4-27 16:54
浏览
3收藏

作者:陈忠蔚

前言

现在应用开发中都不可避免的需要加载一些H5页面。HarmonyOS应用通过 WebView 来提供应用中集成H5页面的能力。在HarmonyOS应用中,出于安全考虑,WebView不支持直接通过File协议加载资源文件或本地文件,所以不能直接通过文件的存放路径,加载本地H5页面,下面介绍一下在HarmonyOS应用中,如何实现加载本地H5页面。

WebView使用介绍

WebView 是一个基于 webkit 引擎、展现 web 页面的控件,可以显示和渲染web页面,相当于应用中的浏览器,可以加载网络上或应用本地的HTML文件。
WebView的能力:

  • 显示和渲染 Web 页面
  • 直接使用 HTML文件(网络上或本地 resources 中)作布局
  • 可和 JavaScript 交互调用

效果展示

HarmonyOS - JavaUI 框架之使用WebView加载本地H5页面-鸿蒙开发者社区

实现步骤

1. 首先在resources目录下创建rawfile文件夹,该目录下的资源会打包进应用内

HarmonyOS - JavaUI 框架之使用WebView加载本地H5页面-鸿蒙开发者社区

2.将H5页面放到entry/src/main/resources/rawfile文件夹下

HarmonyOS - JavaUI 框架之使用WebView加载本地H5页面-鸿蒙开发者社区

3.WebView 要访问本地 Web 文件,需要通过DataAbility 的方式进行访问,这里创建一个 WebAbility.java 文件

在WebAbility中进行本地资源文件的解析,重写 RawFileDescriptor(),获取到我们解析到的RawFileDescriptor对象,RawFileDescriptor可以看作是我们访问HarmonyOS应用本地资源文件的入口,通过该入口可以将我们的H5页面加载到WebView控件上。
注意:private static final String ENTRY_PATH_PREFIX = “entry/resources” 这里将 “entry” 替换成自己对应modul的路径

public class WebAbility 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");
        }

        // 获取uri对应的资源路径 例如:com.example.dataability/entry/resources/rawfile/
        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)) {
            // 打开entry/resources/rawfile目录下的资源
            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)) {
            // 打开手机本地存储目录下的资源
            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() {
                    return fileDescriptor;
                }

                @Override
                public long getFileSize() {
                    return -1;
                }

                @Override
                public long getStartPosition() {
                    return 0;
                }

                @Override
                public void close() throws IOException {
                }
            };
        } catch (IOException e) {
            throw new FileNotFoundException("Not found support local file at " + uri);
        }
    }

4.然后在 “entry/src/main/config.json” 中完成 WebAbility 的声明,代码如下:

 {
        "name": "com.example.webdemo.WebAbility",
        "type": "data",
        "uri": "dataability://com.example.webdemo.dataability"
 },

找到config.json的对应的module,在abilities节点中添加以上代码,具体位置如下:

 "abilities": [
       {
        "name": "com.example.webdemo.WebAbility",
        "type": "data",
        "uri": "dataability://com.example.webdemo.dataability"
      },
      {
        "visible": true,
        "name": "com.example.webdemo.MainAbility",
        "icon": "$media:icon",
        "description": "$string:mainability_description",
        "formsEnabled": true,
        "label": "$string:entry_MainAbility",
        "type": "page",
      }
    ],
......

在abilities中声明的 uri 的值便是webview加载的路径,在WebAbility里面进行了资源文件的解析,当路径指向WebAbility时,H5页面就可以在WebAbility上显示了。

5.创建 WebView 并加载本地页面

在MainAbility的onStart()中创建WebView,并配置支持访问Data Ability资源,支持JavaScript,通过webView.load()加载本地H5页面,加载地址为:“dataability://com.example.webdemo.dataability/rawfile/help-center/index.html#/”,“dataability://com.example.webdemo.dataability”是指向解析本地资源文件的Ability,后面拼接加载页面的路径,具体代码如下:

	DirectionalLayout dLayout = new DirectionalLayout(this);
	dLayout.setLayoutConfig(new ComponentContainer.LayoutConfig(
                ComponentContainer.LayoutConfig.MATCH_PARENT,
                ComponentContainer.LayoutConfig.MATCH_PARENT
        ));
	super.setUIContent(dLayout);
	WebView webView = new WebView(this);
	webView.getWebConfig().setJavaScriptPermit(true);
	webView.getWebConfig().setDataAbilityPermit(true);
	webView.load("dataability://com.example.webdemo.dataability/rawfile/help-center/index.html#/");
	dLayout.addComponent(webView);

总结

实际项目中APP中的H5页面一般都是通过网络获取的,并不需要本地解析资源文件。但是手机断网或者网络不稳定时,可以下载H5页面到本地,通过以上方式使用webview加载本地H5页面,避免出现手机断网或者网络不稳定时页面加载不了的情况。

更多原创内容请关注:中软国际 HarmonyOS 技术团队

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
已于2022-4-27 16:56:34修改
3
收藏 3
回复
举报
1条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

很好的方法,学习了!

回复
2022-4-27 17:43:17
回复
    相关推荐