1. 程式人生 > >Cordova原始碼學習(二)-Native回撥JS

Cordova原始碼學習(二)-Native回撥JS

Native回撥JS

流程圖

解析

  • Native
    Native方法執行完,通過sendPluginResult開始,回撥結果給js

    • sendPluginResult:

      - (void)sendPluginResult:(CDVPluginResult*)result callbackId:(NSString*)callbackId
      {
          int status = [result.status intValue];
          BOOL keepCallback = [result.keepCallback boolValue];
          NSString* argumentsAsJSON = [result argumentsAsJSON];
          BOOL
      debug = NO; NSString* js = [NSString stringWithFormat:@"cordova.require('cordova/exec').nativeCallback('%@',%d,%@,%d, %d)", callbackId, status, argumentsAsJSON, keepCallback, debug]; [self evalJsHelper:js]; }
    • evalJsHelper:
      執行JS,這裡的流程跟JS調Native執行JS一模一樣的程式碼,利用UIWebView-stringByEvaluatingJavaScriptFromString:

      方法執行JS

      - (void)evalJsHelper2:(NSString*)js
      {
          [_viewController.webViewEngine evaluateJavaScript:js completionHandler:^(id obj, NSError* error) {
              // TODO: obj can be something other than string
              if ([obj isKindOfClass:[NSString class]]) {
                  NSString* commandsJSON = (NSString
      *)obj; if ([commandsJSON length] > 0) { CDV_EXEC_LOG(@"Exec: Retrieved new exec messages by chaining."); } [_commandQueue enqueueCommandBatch:commandsJSON]; [_commandQueue executePending]; } }]; }
      • 其執行回撥裡仍然有處理命令佇列的程式碼
  • JS

    • nativeCallback
      這一步,並不是直接就回調結束了,還會通過nativeEvalAndFetch-nativeFetchMessages返回當前的commandQueue裡的內容,會到前一步evaluateJavaScript執行結束的回撥中,直到全部執行結束。觸發cordova.callbackFromNative

      iOSExec.nativeCallback = function(callbackId, status, message, keepCallback, debug) {
          return iOSExec.nativeEvalAndFetch(function() {
              var success = status === 0 || status === 1;
              var args = convertMessageToArgsNativeToJs(message);
              function nc2() {
                  cordova.callbackFromNative(callbackId, success, status, args, keepCallback);
              }
              setTimeout(nc2, 0);
          });
      };
    • callbackFromNative
      這裡的原始碼註釋也非常清楚了,根據Native返回的結果進行回撥處理

      /**
      * Called by native code when returning the result from an action.
      */
      callbackFromNative: function(callbackId, isSuccess, status, args, keepCallback) {
          try {
              var callback = cordova.callbacks[callbackId];
              if (callback) {
                  if (isSuccess && status == cordova.callbackStatus.OK) {
                      callback.success && callback.success.apply(null, args);
                  } else if (!isSuccess) {
                      callback.fail && callback.fail.apply(null, args);
                  }
                  /*
                  else
                      Note, this case is intentionally not caught.
                      this can happen if isSuccess is true, but callbackStatus is NO_RESULT
                      which is used to remove a callback from the list without calling the callbacks
                      typically keepCallback is false in this case
                  */
                  // Clear callback if not expecting any more results
                  if (!keepCallback) {
                      delete cordova.callbacks[callbackId];
                  }
              }
          }
          catch (err) {
              // ...
          }
      }

其他補充

  • CDVViewController

    • 看構成,就知道CDVViewController是作為一個功能整合的類,這裡麵包含的命令佇列、協議代理,在上面都已經有涉及
    • 內部主要初始化外掛、配置、設定代理、處理生命週期
      @interface CDVViewController : UIViewController <CDVScreenOrientationDelegate>{
          @protected
          id <CDVWebViewEngineProtocol> _webViewEngine;
          @protected
          id <CDVCommandDelegate> _commandDelegate;
          @protected
          CDVCommandQueue* _commandQueue;
          NSString* _userAgent;
      }
  • CDVUIWebViewEngine:CDVPlugin 以外掛的形式實現

    • 成員變數engineWebView,建立webview,賦值engineWebView
    • pluginInitialize,初始化外掛,設定代理。CDVUIWebViewNavigationDelegate代理在此處設定

相關推薦

Cordova原始碼學習()-NativeJS

Native回撥JS 流程圖 解析 Native Native方法執行完,通過sendPluginResult開始,回撥結果給js sendPluginResult:

混合應用開發框架Cordova原始碼學習總結

有說法是,採用混合模式的WEBVIEW來開發介面,通常適用於需要經常變更的頁面,比方活動頁,或者其他展示頁面;相對行業應用來說,哪些使用原生介面開發,哪些使用WEBVIEW來開發,需要從我們當前的痛點出發來考慮,當前行業應用主要是開發週期相對長,採用WEBVIEW的方式來開發,在通用基礎

基於MQTT協議的 org.eclipse.paho.client.mqttv3 原始碼學習()

一、主要類介紹 二、重點類程式碼分析 對於長連線,一般是直接從訊息的接收和傳送類開始讀,上面知道paho中訊息傳送和接收是在CommsSender和CommsReceiver實現的, 所以直接差看CommsSender程式碼。 [ja

python學習筆記(60) 和爬蟲

from multiprocessing import Poolimport requestsdef get(url): response = requests.get(url) if response.status_code == 200: return url,response.

Vue原始碼學習 ———— Vue原型物件包裝

Vue原型物件的包裝 在Vue官網直接通過 script 標籤匯入的 Vue包是 umd模組的形式。在使用前都通過 new Vue({})。記錄一下 Vue建構函式的包裝。 在 src/core/instance/index.js 這個檔案是 Vue建構函式的出生地。 import { initMixi

微信小程式學習筆記 ( 小程式主體學習 邏輯層 app.js 擴充套件 高階食用方法)

目錄結構 上圖是我建立的的微信小程式的目錄結構 主體學習 邏輯層(App Service)    小程式開發框架的邏輯層由 JavaScript 編寫。    邏輯層將資料進行處理後傳送給檢視層,同時接受檢視層的事件反饋。

nginx原始碼學習() 記憶體池結構 ngx_pool_t

1,nginx的記憶體池介紹     為了方便系統模組對記憶體的使用,方便記憶體的管理,nginx自己實現了程序池的機制來進行記憶體的分配和釋放, 首先nginx會在特定的生命週期幫你    統一建立記憶體池,當需要進行記憶體分配的時候統一通過記憶體池中的記憶體進行分配,最

Python學習--day35-非同步 協程

day36 非同步回撥與協程 一、非同步回撥 1、什麼是回撥: 非同步回撥指的是:在發起一個非同步任務的同時指定一個函式,在非同步任務完成時會自動的呼叫這個函式。 2、為什麼需要回調函式 需要獲取非同步任務的執行結果,但是又不應該讓其阻塞(降低效率),即想要高效的獲取任務的執行結果。 之前

element原始碼學習 —— 簡單元件學習

上一篇部落格中學習了專案的結構,這篇部落格來學幾個簡單的元件的實現。 在上一篇部落格中我們提到了元件的原始碼都是存放在 packages 目錄下的,所以我們從中挑一些元件來學習。先從簡單的入手,來學習 button、radio、checkbox和Inp

vue 原始碼學習 例項初始化和掛載過程

vue 入口 從vue的構建過程可以知道,web環境下,入口檔案在 src/platforms/web/entry-runtime-with-compiler.js(以Runtime + Compiler模式構建,vue直接執行在瀏覽器進行編譯工作) import Vue from './runtime/

vue 原始碼學習() 例項初始化和掛載過程

vue 入口 從vue的構建過程可以知道,web環境下,入口檔案在 src/platforms/web/entry-runtime-with-compiler.js(以Runtime + Compiler模式構建,vue直接執行在瀏覽器進行編譯工作) import Vue from './runtime/

jQuery原始碼學習()

回撥物件Callbacks 回撥物件Callbacks就是用來管理回撥函式佇列的。 引數說明 它提供幾個便捷的處理引數 once: 確保這個回撥列表只執行一次 memory: 保持以前的值,將新增到這個列表的後面的最新的值立即執行呼叫任何回撥 u

ROS學習之 cpp函式和輪轉(spin)

wiki連結: http://wiki.ros.org/roscpp/Overview/Callbacks%20and%20Spinning 資料(雲飛機器人實驗室的一篇小文): http://www.yfworld.com/?p=2318 這篇文章會幫助理解ros::s

lua_gc 原始碼學習

普及下常識:GC 是 garbage collector 資源回收器; 初期的 Lua GC 採取的是 stop the world 的實現。一旦產生 gc 就需要期待全部 gc 流程走完。lua 自己是個很精簡的體系,但不代表處理的資料量也必然很小。 從 Lua 5.1

vue學習:用 Vue.js + Vue Router 創建單頁應用的幾個步驟

新建 inf 操作 span config pos main 分享 rom 通過vue學習一:新建或打開vue項目,創建好項目後,接下來的操作為: src目錄重新規劃——>新建幾個頁面——>配置這幾個頁面的路由&

Mybatis 原始碼學習() Mapper 介面和sql的對映

問題:xml中的sql語句是怎麼被對映到Mapper介面的一個方法上的?弄明白了mapper是如何註冊的了以後,發現xml檔案中的namespace是關鍵。實際還是去找那個java介面檔案。那麼找到了介面檔案,註冊了mapper那這個mapper又是怎麼反過來找到xml中配置

GoLang學習筆記(十)匿名函式及用法

Go語言支援匿名函式,即在需要使用函式時,再定義函式。 匿名函式沒有函式名,只有函式體,函式可以被作為一種型別被賦值給變數,匿名函式也往往以變數的方式被傳遞。 匿名函式經常被用於實現回撥函式、閉包等。 定義格式: func(引數列表)(返回引數列表){    //函式體 }

Lua 入門學習教程() 函式 與 函式

還記得開始學C語言的時候,書上就拿兩個數相加 作為例子,來介紹函式。我也拿 Add 來說吧。 函式的簡單寫法就像下面的Add local function Add( a,b ) -- body print(a+b) end Add(10,20) 然後面向物件 loca

【JavaScript 學習--12】JS深入理解呼叫棧,事件迴圈機制,佇列

最近研究JavaScript裡的函式事件這些到底是如何呼叫的,查閱了好些資料,特別是國外一些大牛寫的文章,啟發非常的大,於是打算對這些知識進行梳理。 基本知識 JS是什麼? JS是單執行緒,非阻塞,非同步,併發的語言 JS有 呼叫棧,事件迴圈,回撥

iOS: Native呼叫js的方法以及jsnative的方法

背景: UIWebView: iOS 用來展示 web 端內容的控制元件。 1. 核心方法: - (NSString*)stringByEvaluatingJavaScriptFromString:(NSString *)script; script 就是 JS