一次技术选型(webView加载h5)

背景

公司有写好的前端,其中包括

  1. 原生不太好实现的动画
  2. 动作跟情绪识别的model(利用的是tensorflow.js)
  3. 音视频

android端也希望可以实现相同的功能,此时想到的可能就是通过webview直接加载一个url就可以了,简单快捷。但是产品希望用户在没有网络的情况下也可以使用,直接加载url的方案肯定是行不通的。此时想到的方案是把前端的代码build到apk中,也就是把前端代码放在assets目录中。

方案确定之后开始爬坑~

一:如何将vue前端代码添加到assets中

将前端build之后生成的dist文件夹copy到assets中,之后使用webview加载assets中的入口html。

加载之后webview一片空白

问题出在了前端build之后的引用资源(css,js等)路径上。前端配置文件中assetsPublic的属性为“/”,对应的是根目录,而引用的资源文件static/css/xx.css目录和index.html是同级的,去根目录下找自然就找不到资源。修改配置文件中的assetsPublic属性为“./”,再重新build解决问题。

二:如何使用chrome调试webview显示的h5页面

加载webview空白的问题,我们是如何定位到的呢。其实chrome提供了调试andorid WebView的功能,inspect之后可以在console中看到报错信息。至于如何调试,过程非常简单,两三步就可以,想自己体验的可以百度下,个人感觉还是非常实用的~(注意在webView中设置debug模式为true)

三:webView如何加载具有音视频功能的h5页面

有两种方案可以选择:

  1. 通过原生跟前端交互实现(需要修改前端代码,android端也有一定的工作量)
  2. webView在5.0之后默认支持WebRtc(支持网页实时语音跟视频对话),需要新建一个WebChromeClient设置给webView,其中WebChromeClient需要重写onPermissionRequest()方法赋予网页音视频权限。另外需要在manifest中声明使用的音视频权限。
四:跨域问题

webView加载assets中的静态html使用的是file协议,如果在index.html中再去加载http协议的页面或者发送ajax请求都会有跨域的问题。

实际项目中加载model使用到了http协议。

方案:可以使用NanoHttpd或者AndroidAsync在app中搭建本地服务器。

webView使用loadUtl(http)的形式加载index.html,这样统一使用http协议。

NanoHttpd不支持ttf以及woff等格式,最终使用了AndroidAsync跑通了demo。

具体可以参考demo中的代码或者google 百度。

五:跨域问题备选方案

要求提供pb格式的model,之后使用tensorflowLite(tensorFlow对android的解决方案)去跟model交互,交互完成之后再去跟前端h5交互。

六:webView跟js交互

dist放在本地之后webview直接load一直担心vue build之后生成的dist中的js文件加了类似android的混淆,可能h5跟android交互会有问题,测试证明我的担心是多余的😓。交互跟直接load服务器中的h5是一样的。可以参考下:

https://juejin.im/post/5b7d30dfe51d4538b2046d63

七:demo地址

https://github.com/kbjay/AndroidAsyncDemo