• cordova与ios native code交互的原理


    非常早曾经写了一篇博客,总结cordova插件怎么调用到原生代码:cordova调用过程,只是写得太水。基本没有提到原理。近期加深了一点理解,又一次补充说明一下

    js调用native

    以下是我们产品中的代码片段:

    datePicker.show(options, function (date) {
        var month = date.getMonth() + 1;
        callback(null, date.getFullYear() + "-" + month + "-" + date.getDate());
    });

    cordova插件终于表现出来的都是js接口,而且调用者全然不须要知道自己在调用一个cordova插件

    可是在不论什么cordova js方法内部,最后一定会调用cordova.exec函数:

    cordova.exec(successCallback, errorCallback, "DatePicker", "show", []);

    然后就进入了关键的cordova.exec函数。这是cordova框架的js端的最后一环。就是由它完毕对ios native的调用

    在exec函数里,首先会推断平台。可能是android,ios或者wp,其它平台本文省略。假设是ios平台,cordova会採用下面2种方式的一种。来与ios native code交互

    通过iframe

    cordova.exec往当前的html中插入一个不可见的iframe,从而向UIWebView请求载入一个特殊的URL。这个URL里当然就包括了要调用的native plugin的类名,方法名,參数,回调函数等信息

    接下来。因为被请求载入URL,于是UIWebViewDelegate的这种方法被调用:

    - (BOOL)webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType

    这里就进入了native側,从request里就拿到了js端传过来的信息,然后调用到native plugin

    通过XHR

    还有一种方式,cordova.exec里直接发起一个XHR请求,被native側的NSURLProtocol拦截,于是调用到这个native方法:

    + (BOOL)canInitWithRequest:(NSURLRequest*)theRequest

    也进入了native側。然后以相同的方式调用到native plugin

    在2种方式中,cordova会优先选择XHR方式。仅仅有当XHR方式不可用时,才会使用iframe的方式。

    只是不管怎么样。这2种方法都为从js到native打开了一条通道,剩下的就是传递參数和路由的问题了

    native调用js

    还有一条通道就简单的多,由于iOS提供了原生支持,所以不须要想特别的办法。即通过UIWebView的这种方法:

    - (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;

    看一下cordova框架native側的代码,我去掉了凝视和无关代码:

    - (void)evalJsHelper:(NSString*)js
    {
        if (![NSThread isMainThread] || !_commandQueue.currentlyExecuting) {
            [self performSelectorOnMainThread:@selector(evalJsHelper2:) withObject:js waitUntilDone:NO];
        } else {
            [self evalJsHelper2:js];
        }
    }

    - (void)evalJsHelper2:(NSString*)js
    {
        NSString* commandsJSON = [_viewController.webView stringByEvaluatingJavaScriptFromString:js];
    }

    能够看到,正是通过UIWebView提供的这种方法完毕的,可是,一定运行在main thread

    同步和异步的问题

    从上面的分析能够发现。从js调用native,2种方式都必然是异步的。而从native回到js。却是一个同步的方法,并且是跑在主线程里

    调用cordova插件的代码,对返回值的处理一定要放在回调函数里。由于结果是异步返回的。同一时候,回调函数的运行时间不能太长,否则会堵塞native主线程

    參考

    本文參考了下面2篇文章,都写得非常好:

    iOS版PhoneGap原理分析

    浅析Cordova for iOS




  • 相关阅读:
    聊聊Unity2018的LWRP和混合光照
    不能直接获取?聊聊如何在Shader Graph中获取深度图
    还原堆栈信息,分析地形系统使用ASTC格式的纹理导致Crash的问题
    巧妙设置Texture Type,将ShadowMask内存占用变成之前的1/4
    开发自定义ScriptableRenderPipeline,将DrawCall降低180倍
    Signed Distance Field Shadow in Unity
    Daily Pathtracer!安利下不错的Pathtracer学习资料
    聊聊LightProbe原理实现以及对LightProbe数据的修改
    Scala学习笔记(六):本地函数、头等函数、占位符和部分应用函数
    Scala学习笔记(五):内建控制循环
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/6768191.html
Copyright © 2020-2023  润新知