hybrid App中js调用native接口原理

JavaScript019

hybrid App中js调用native接口原理,第1张

移动网络的发展推动移动APP盛行,目前市场上APP开发技术的类型主要有三种,native开发、hybrid开发、RN/weex开发。

本文主要讲述hybrid APP中js调用native原理。hybrid APP就是利用Android/iOS上webview加载web网页,其实就是相当于用native做了一个外壳,然后里面加载网页。那站在业务层面上,只要没有太依赖性能,都能满足需求,那这里面有可能会用到一些硬件功能,比如:相机、位置等,这时就必须调用native。

1.js 调用 native,Android里面主要通过WebViewClient.shouldOverrideUrlLoading方法拦截指定格式的URL,通过拦截特定URL和获取对应的参数,来调用native对应的功能。这里我们主要通过cordova插件,来做例子说明

上面我们看到cordova的初始化,这里面主要对回调callback进行定义,js调用native之后,native处理完结果,将结果返回js,就是通过callback完成。

3.构造链接,并发送链接pokeNative

这里我们看到调用native可以通过iframe和通过XHR完成。

这就是js调用native的方式,native完成处理之后,通过webView.addJavascriptInterface调用js中挂载在window对象的方法,这是一个统一的回调nativeCallback ,通过callbackID识别出本次结果需要回调js中的哪个function。然后本次交互就全部完成了

总结一下,主要同理是通过native两个方法:addJavascriptInterface和shouldOverrideUrlLoading完成js和native交互。

HTML5-Web Workers实现多线程:

当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成。虽然在JavaScript中有setInterval和setTimeout函数使javaScript看起来好像使多线程执行,单实际上JavaScript使单线程的,一次只能做一件事情。

可以运行以下示例,检验js的单线程特性。

相关代码请到github查看。

<div id='container'></div>

<script>

window.alert('hi')

setTimeout(function(){

var ul = document.createElement('ul')

var li = document.createElement('li')

var text = document.createTextNode('world')

var container = document.getElementById('container')

li.appendChild(text)

ul.appendChild(li)

container.appendChild(ul)

console.log('done!')

},2000)

</script>123456789101112131415123456789101112131415

如果JavaScript是多线程,在弹出警告框两秒后,页面应该出现一个li标签(内容为world)。事实上因为JavaScript是单线程,所以如果你不点击弹出框的确定按钮,world这个li永远也出不来。

点击确定后

web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。您可以继续做任何愿意做的事情:点击、选取内容等等,而此时 web worker 在后台运行。

我们需要把希望单独执行的javascript代码放到一个单独的js文件中,然后在页面中调用Worker构造函数来创建一个线程,参数是该文件路径,参数存放如果是相对地址,那么要以包含调用Worker构造函数语句所在脚本为参照,如果是绝对路径,需要保证同源(协议+主机+端口)。这个文件不需要我们在页面使用script标签显示引用。

var worker = new Worker('src/js/worker.js')11

我们可以看到worker对象只有两个属性,其实是两个回调函数句柄

onerror:当worker运行出现错误,并且没有在worker中ing捕获,会在此捕获

onmessage:当worker向主线程发送消息是调用

在其prototype内有两个重要方法

postMessage:很熟悉的赶脚,之前我们介绍过window对象的postMessage()方法,woker的postMessage方法和window的比较类似,但参数略有不同,只需要传递消息内容就可以,而且支持所有JavaScript原生数据类型,当然不放心的话同样也可以序列化为字符串传递

terminate:终止worker执行,有些worker执行比较慢,主线程可以主动终止其执行

下面我们用web workers重写上面那个例子。

相关代码请到github查看。

test_web_worker.html

<script>

var worker = new Worker('./worker.js')

window.alert('hi')

</script>12341234

worker.js

setTimeout(function(){console.log('done!')},2000)