Cordova源码学习(二)-Native回调JS

38 篇文章 1 订阅
2 篇文章 0 订阅

本文只对JS与Native之间的交互进行源码阅读。至于Cordova如何开发插件等等,请参考Cordova官方文档:https://cordova.apache.org/docs/en/latest/

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代理在此处设置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值