Hybrid-APP技术原理( 二 )


JS调用在没经过客户端注入的时候 , 直接使用调用callNativeFunction会报callNativeFunctionisnotdefined这个错误 , 说明此时JS上下全文全局 , 是没有这个函数的 , 调用无效 。
在执行完客户端注入后 , 此时JS上下文全局对象下面 , 就拥有了这个callNativeFunction的函数对象 , 就可以正常调用 , 从而传递数据到Native 。

Hybrid-APP技术原理
文章图片
2.2.4、安卓addJavaInterface注入
客户端注入安卓的WebView有一个接口addJavaInterface , 可以在loadUrl之前提前准备一个对象 , 通过这个接口注入给JS上下文 , 从而让JS能够操作 , 这个操作方式很类似苹果UIWebviewJavaCore注入 , 整个机制也差别不大 。
JS调用在android端注入的对象同样也被挂载在JS上下文全局对象下面 , 直接访问即可调用 。

Hybrid-APP技术原理
文章图片
2.2.5、苹果WKWebViewMessageHandler注入
客户端注入苹果在开放WKWebView这个性能全方位碾压UIWebView的web组件后 , 也大幅更改了JS与Native交互的方式 , 提供了专有的交互APIMessageHandler
需要注意的是如果当前WebView没用了 , 需要销毁 , 需要先移除这个对象注入 , 否则会造成内存泄漏 , WebView和所在VC循环引用 , 无法销毁 。
JS调用这里不像前边两个注入一样 , 直接注入到JS上下文全局对象里 , addMessageHandler方法注入的对象被放到了 , 全局对象下一个Webkit对象下面 。
并且调用方式和之前的两种方法也不同 , 前两种都可以让js任意操作所注入自定义对象的所有方法 , 而addMessageHandler注入其实只给注入对象起了一个名字nativeObject , 但这个对象的能力是不能任意指定的 , 只有一个函数postMessage 。

Hybrid-APP技术原理
文章图片
2.2.6、evaluatingJava执行JS代码
前面也简单介绍了一下 , JS是一个脚本语言 , 可以在无需编译的情况下 , 直接输入字符串JS代码 , 直接运行执行看结果 , 这也是为什么在Chrome里 , 在网页运行的时候打开控制台 , 可以输入各种JS指令的看结果的 。
也就是说当Native想要调用JS的时候 , 可以由Native把需要数据与调用的JS函数 , 通过字符串拼接成JS代码 , 交给WebView进行执行 。
【Hybrid-APP技术原理】Android/iOS-UIWebView/iOS-WKWebView , 都支持这种方法 , 这是目前最广泛运用的方法 。

Hybrid-APP技术原理
文章图片
2.2.7、loadUrl执行JS代码
安卓在4.4以前是不能用evaluatingJava这个方法的 , 因此之前安卓都用的是webview直接loadUrl , 但是传入的url并不是一个链接 , 而是以”java:”开头的js代码 , 从而达到让webview执行js代码的作用 。

Hybrid-APP技术原理
文章图片
2.2.8、WKUser执行JS代码
对于iOS的WKWebView , 除了evaluatingJava , 还有WKUser这个方式可以执行JS代码 , 他们之间是有区别的 , 这个虽然是一种通信方式 , 但并不能随时随地进行通信 。
evaluatingJava是在客户端调用的时候js端会立刻执行代码 。 WKUser是预先准备好JS代码 , 当WKWebView加载Dom的时候 , 执行当条JS代码 。
Hybrid-APP技术原理
文章图片
2.3、JS主动调用Native的方案对比

Hybrid-APP技术原理
文章图片
三、cordova运行原理
在了解了Hybridapp核心的通信方案之后 , 我们接下来看看目前公司使用最广泛的跨平台技术cordova的运行原理是怎么样的 。
3.1、客户端入口
这里客户端以Android端为例分析 , Android端默认的入口是mainActivity类 , 我们可以看到它其实继承CordovaActivity类 , 一切初始化条件是从loadUrl方法开始 。

Hybrid-APP技术原理
文章图片
3.2、Android端核心类CordovaActivity

Hybrid-APP技术原理
文章图片
CordovaActivity内依赖一个WebView类 , 一个Preferences类 , 一个CordovaInterface接口 , 并同时初始化一些配置信息 。 WebView具体实现是由CordovaWebViewImpl类 , CordovaInterface接口具体实现是由CordovaInterfaceImpl类实现 。
CordovaWebViewImpl是核心类 , 里面会把一些插件能力初始化 , 用一个PluginManager进行管理 , 包含一个引擎类—CordovaWebViewEngine , 这个引擎是通过反射的方式创建 , 自身初始化的时候把NativeToJsMessageQueue关联起来 , 里面包含着以Js字符串为主的双向链表 , 把每次从前端通过JS代码存储起来 , 然后通过绑定的桥接方式Pop出到相应的Native代码中去 。