cordova與ios native code互動的原理

來源:互聯網
上載者:User

標籤:ios   cordova   原理   phonegap   

很早以前寫了一篇部落格,總結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




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.