潍坊企业网站模板建站,制作网站模板的发展空间,wordpress 读书主题,公司做网站都需要什么流程源宝导读#xff1a;Hybrid-APP技术不仅具有“Native APP的良好交互体验”同时也具备“Web APP跨平台开发的优势”。既然Hybrid-APP有这么多优势#xff0c;那么究竟什么样的APP才算Hybrid App呢#xff1f;本文将分享我们的技术研究成果。一、什么是Hybrid-APP狭义的Hybrid… 源宝导读Hybrid-APP技术不仅具有“Native APP的良好交互体验”同时也具备“Web APP跨平台开发的优势”。既然Hybrid-APP有这么多优势那么究竟什么样的APP才算Hybrid App呢本文将分享我们的技术研究成果。一、什么是Hybrid-APP狭义的Hybrid也是现在大家普遍认知的Hybrid就是一种给 WebView 增加一些js通信可以调用原生API的方式。广义Hybrid前端的开发思路与客户端原生的开发思路相结合。通过原生的配合把原本js or 前端开发做不到的事情做到了用原生的方式增强了原本的前端技术能力。WebViewBridge、RN、weex、小程序。 我能否认为只要是前端的开发思路与客户端原生的开发思路相结合就认为他是一种Hybrid 通过原生的配合把原本js or 前端开发做不到的事情做到了用原生的方式增强了原本的前端技术能力是否就是一种 Hybrid 无论是WebViewBridge也好RN类似的原生渲染框架也好小程序也好某种意义上讲他们都算HybridHybrid框架-基本能力 接下来我们来看一下一个Hybrid框架所需要具备的基本能力跨平台能力。 这也是Hybrid应用与原生应用相比最大的优点一次编写随处运行。灵活的业务模块扩展能力。良好的调用原生功能的能力。 由于在APP中有些功能必须由原生端提供所以还需要有良好的调用原生功能的能力。快速更新迭代的能力。 使用原生技术开发的APP每次更新都需要上传应用商店审核但是使用Hybrid技术开发的应用可以绕过应用商店实现热更新。二、Hybrid-APP中通信方案 在Hybrid APP中最核心的技术就在于前端与客户端如何通信接下来我们看一下js与native之间是如何通信的。2.1、JS 调用 Native 的几种方法假跳转的请求拦截A标签跳转。原地跳转。iframe跳转。弹窗拦截alert()prompt()confirm()JS上下文注入苹果JavaScriptCore注入。安卓addJavascriptInterface注入。苹果scriptMessageHandler注入。2.2、Native 调用 JS 的几种方法evaluatingJavaScript 直接注入执行JS代码 JS是一个脚本语言任何一个JS引擎都可以在任意时机直接执行JS代码我们可以把任何Native想要传递的消息/数据直接写进JS代码中。loadUrl 浏览器用’javascript:’JS代码做跳转地址 在浏览器中可以直接用’javascript:xxxx’来简单的执行一些JS代码这个方法只有安卓可以用因为iOS必须先将url字符串生成Request再交给webview去loadWKUserScript WKWebView的 addUserScript 方法 WKWebView官方提供了一个Api可以让WebView在加载页面的时候自动执行注入一些预先准备好的JS2.2.1、假跳转的请求拦截 假跳转的请求拦截 就是由网页发出一条新的跳转请求跳转的目的地是一个非法的压根就不存在的地址。 url地址由协议、域名、路径、参数这么几个部分构成我们可以构建一条假的url用协议与域名当做通信识别、用路径当做指令识别、用参数当做数据传递。 客户端会无差别拦截所有请求真正的url地址应该照常放过只有协议域名匹配的url地址才应该被客户端拦截拦截下来的url不会导致webview继续跳转错误地址因此无感知相反拦截下来的url我们可以读取其中路径当做指令读取其中参数当做数据从而根据约定调用对应的native原生代码。JS发起调用 JS其实有很多种方式发起假请求跟发起一个新请求没啥两样只要按协议约定 生成假请求地址正常的发起跳转即可任何一种方式都可以让客户端拦截住。客户端拦截安卓的拦截方式shouldOverride UrlLoading。UIWebView的拦截方式webView: shouldStartLoadWithRequest :navigationType。WKWebView的拦截方式webView: decidePolicyForNavigationAction :decisionHandler。2.2.2、弹窗拦截JS发起调用 可以使用alert/confirm/prompt三种弹框每种弹框都可以由JS发出一串字符串用于展示在弹框之上而此字符串恰巧就是可以用来传递数据我们把所有要传递通讯的信息都封装进入一个js对象然后生成字典最后序列化成json转成字符串。客户端拦截安卓的拦截方式onJsPrompt。UIWebView的拦截方式不支持截获任何一种弹框。WKWebView的拦截方式webView: runJavaScriptText InputPanelWith Prompt :balbala。2.2.3、苹果UIWebview JavaScriptCore注入客户端注入 UIWebView可以通过KVC的方法直接拿到整个WebView当前所拥有的JS上下文documentView.webView.mainFrame.javaScriptContext。 拿到了JSContext一切的使用方式就和直接操作JavaScriptCore没啥区别了我们可以把任何遵循JSExport协议的对象直接注入JS让JS能够直接控制和操作。JS调用 在没经过客户端注入的时候直接使用调用callNativeFunction()会报 callNativeFunction is not defined这个错误说明此时JS上下全文全局是没有这个函数的调用无效。 在执行完客户端注入后此时JS上下文全局对象下面就拥有了这个callNativeFunction的函数对象就可以正常调用从而传递数据到Native。2.2.4、安卓addJavascriptInterface注入客户端注入 安卓的WebView有一个接口addJavascriptInterface可以在loadUrl之前提前准备一个对象通过这个接口注入给JS上下文从而让JS能够操作这个操作方式很类似苹果UIWebview JavaScriptCore注入整个机制也差别不大。JS调用 在android端注入的对象同样也被挂载在JS上下文全局对象下面直接访问即可调用。2.2.5、苹果WKWebView scriptMessage Handler注入客户端注入 苹果在开放WKWebView这个性能全方位碾压UIWebView的web组件后也大幅更改了JS与Native交互的方式提供了专有的交互APIscriptMessageHandler需要注意的是如果当前WebView没用了需要销毁需要先移除这个对象注入否则会造成内存泄漏WebView和所在VC循环引用无法销毁。JS调用 这里不像前边两个注入一样直接注入到JS上下文全局对象里addScriptMessageHandler方法注入的对象被放到了全局对象下一个Webkit对象下面。 并且调用方式和之前的两种方法也不同前两种都可以让js任意操作所注入自定义对象的所有方法而addScriptMessageHandler注入其实只给注入对象起了一个名字nativeObject但这个对象的能力是不能任意指定的只有一个函数postMessage。2.2.6、evaluatingJavaScript 执行JS代码 前面也简单介绍了一下JS是一个脚本语言可以在无需编译的情况下直接输入字符串JS代码直接运行执行看结果这也是为什么在Chrome里在网页运行的时候打开控制台可以输入各种JS指令的看结果的。 也就是说当Native想要调用JS的时候可以由Native把需要数据与调用的JS函数通过字符串拼接成JS代码交给WebView进行执行。 Android/iOS-UIWebView /iOS-WKWebView都支持这种方法这是目前最广泛运用的方法。2.2.7、loadUrl 执行JS代码 安卓在4.4以前是不能用evaluatingJavaScript 这个方法的因此之前安卓都用的是webview直接loadUrl但是传入的url并不是一个链接而是以”javascript:”开头的js代码从而达到让webview执行js代码的作用。2.2.8、WKUserScript 执行JS代码 对于iOS的WKWebView除了evaluatingJavaScript还有WKUserScript这个方式可以执行JS代码他们之间是有区别的这个虽然是一种通信方式但并不能随时随地进行通信。evaluatingJavaScript 是在客户端调用的时候js端会立刻执行代码。WKUserScript 是预先准备好JS代码当WKWebView加载Dom的时候执行当条JS代码。2.3、JS主动调用Native的方案对比三、cordova运行原理 在了解了Hybrid app核心的通信方案之后我们接下来看看目前公司使用最广泛的跨平台技术cordova的运行原理是怎么样的。3.1、客户端入口 这里客户端以Android端为例分析Android端默认的入口是mainActivity类我们可以看到它其实继承CordovaActivity类一切初始化条件是从loadUrl方法开始。3.2、Android端核心类CordovaActivity CordovaActivity内依赖一个WebView类一个Preferences类一个CordovaInterface接口并同时初始化一些配置信息。WebView具体实现是由CordovaWebViewImpl类CordovaInterface接口具体实现是由CordovaInterfaceImpl类实现。 CordovaWebViewImpl是核心类里面会把一些插件能力初始化用一个PluginManager进行管理包含一个引擎类—CordovaWebViewEngine这个引擎是通过反射的方式创建自身初始化的时候把NativeToJsMessageQueue关联起来里面包含着以Js字符串为主的双向链表把每次从前端通过JS代码存储起来然后通过绑定的桥接方式Pop出到相应的Native代码中去。 最终实现由SystemWebViewEngine类来对Android系统中WebView控件进行二次包装这个类的初始化是在CordovaWebViewImpl类反射创建相关插件和消息传递也是通过SystemWebViewEngine进行绑定。3.3、JS端cordova初始化 Android端调用loadUrl后会启动webview加载前端代码首先会加载运行cordova.js中的代码在cordova.js中会运行cordova/init模块对cordova进行一个初始化初始化中主要的核心操作就是检查监听核心事件是否触发、平台初始化工作、加载插件js。3.4、JS端平台启动处理 不同的平台中平台启动处理的模块会有一些差异但是核心处理相差不大在Android平台中主要进行了三个处理初始化通信模块、处理物理按键的事件、在onCordovaReady事件被触发时通知原生端展示webview。3.5、JS端插件加载处理 插件js加载处理中主要先会通过load方法加载cordova_plugins.js获取到项目中用到的插件然后通过injectScript方法加载插件js可以看到整个加载过程都是通过添加script标签进行加载的所以一旦插件数量很多对加载速度会有一定的影响。 这里只是加载插件的js代码原生端的插件加载并不是在这里进行的。3.6、Cordova启动流程 最后来总结一下整个cordova的启动流程主要做了三个大的事情原生端启动webview加载前端代码。初始化插件。建立通信通道。3.7、Cordova通信流程 启动cordova后在项目运行的过程中当前端需要调用native的能力时就需要与native端进行通信Cordova通信流程中主要有这么几点Cordova通过在原生端与js端维护两个消息队列来处理消息回调。Cordova在执行完exec()后android会马上从消息队列中取出数据同步返回但不一定就是该次请求的数据。js端通过轮询获取原生端消息队列中的数据。四、总结 Hybrid 的宗旨就是如果 WebView 本身做不到或者做起来有很大限制或者性能不佳那么可以让原生配合一起做到。 因为Hybrid本是一个面向业务服务的东西如果业务的野心足够大WebView 容器的想象空间应该是在能力上与RN/小程序看齐的WebView 在 Hybrid 的支持下不单纯是使用Bridge 调用几个原生 API 的事。 我们完全可以拆解RN中的每个环节把RN号称比 WebView 好的原生渲染/原生组件拆解融入 WebView我也可以学习小程序保持 WXML/WXSS的开发方式而非RN那样统一用JSX开发。 这种拆解不是将所有框架优点塞在一个大而全的框架中各种优化方案的选择背后一定带来的是一些取舍。谁来决定取舍业务决定如果自己能深度把握这里面的设计思想就不用在乎什么新的轮子新的框架取其设计优点融入自己的业务之中即可。------ END ------作者简介李同学 前端研发工程师目前负责天际移动平台的相关研发工作。也许您还想看微前端架构在容器平台的应用前端数据层落地实践移动建模平台元数据存储架构演进AI云店小程序演变之路基于 Go 的微服务运行情况监控实践