本文主要是介绍Cordova源码深入分析-第五讲,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
上一讲将主体流程和框架都已经介绍完了,
再次查看整个代码的时候,发现我还是有一些细节并没有列举出来,
例如之前只是介绍了addJavaScript一种方式实现通信,实际上还有另一种通信方式就是prompt方式,本讲再次介绍一下。
prompt有几个优势:
1.可以避免掉android 4.2以下,js安全问题
2.可以实现同步调用,直接返回值
下面开始分析代码逻辑:
重复的位置,不再累述。直接来到cordova.js中
define("cordova/android/nativeapiprovider", function(require, exports, module) {var nativeApi = this._cordovaNative || require('cordova/android/promptbasednativeapi');//这里其实如果没有定义_cordovaNative就会走prompt
var currentApi = nativeApi;module.exports = {get: function() { return currentApi; },setPreferPrompt: function(value) {currentApi = value ? require('cordova/android/promptbasednativeapi') : nativeApi;},// Used only by tests.set: function(value) {currentApi = value;}
};});
而在使用prompt方式的时候,方法都是一样的。
define("cordova/android/promptbasednativeapi", function(require, exports, module) {module.exports = {exec: function(bridgeSecret, service, action, callbackId, argsJson) {return prompt(argsJson, 'gap:'+JSON.stringify([bridgeSecret, service, action, callbackId]));//直接进入java端,代码片段1},setNativeToJsBridgeMode: function(bridgeSecret, value) {prompt(value, 'gap_bridge_mode:' + bridgeSecret);},retrieveJsMessages: function(bridgeSecret, fromOnlineEvent) {return prompt(+fromOnlineEvent, 'gap_poll:' + bridgeSecret);}
};});
代码段1:SystemWebChromeClient.java
@Overridepublic boolean onJsPrompt(WebView view, String origin, String message, String defaultValue, final JsPromptResult result) {// Unlike the @JavascriptInterface bridge, this method is always called on the UI thread.String handledRet = parentEngine.bridge.promptOnJsPrompt(origin, message, defaultValue);//代码片段2if (handledRet != null) {result.confirm(handledRet);} else {dialogsHelper.showPrompt(message, defaultValue, new CordovaDialogsHelper.Result() {@Overridepublic void gotResult(boolean success, String value) {if (success) {result.confirm(value);} else {result.cancel();}}});}return true;}
代码片段2:CordovaBridge.java
public String promptOnJsPrompt(String origin, String message, String defaultValue) {if (defaultValue != null && defaultValue.length() > 3 && defaultValue.startsWith("gap:")) {JSONArray array;try {array = new JSONArray(defaultValue.substring(4));int bridgeSecret = array.getInt(0);String service = array.getString(1);String action = array.getString(2);String callbackId = array.getString(3);String r = jsExec(bridgeSecret, service, action, callbackId, message);//执行与之前介绍的逻辑一样的流程中了return r == null ? "" : r;} catch (JSONException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return "";}// Sets the native->JS bridge mode.else if (defaultValue != null && defaultValue.startsWith("gap_bridge_mode:")) {try {int bridgeSecret = Integer.parseInt(defaultValue.substring(16));jsSetNativeToJsBridgeMode(bridgeSecret, Integer.parseInt(message));} catch (NumberFormatException e){e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return "";}// Polling for JavaScript messageselse if (defaultValue != null && defaultValue.startsWith("gap_poll:")) {int bridgeSecret = Integer.parseInt(defaultValue.substring(9));try {String r = jsRetrieveJsMessages(bridgeSecret, "1".equals(message));return r == null ? "" : r;} catch (IllegalAccessException e) {e.printStackTrace();}return "";}else if (defaultValue != null && defaultValue.startsWith("gap_init:")) {// Protect against random iframes being able to talk through the bridge.// Trust only pages which the app would have been allowed to navigate to anyway.if (pluginManager.shouldAllowBridgeAccess(origin)) {// Enable the bridgeint bridgeMode = Integer.parseInt(defaultValue.substring(9));jsMessageQueue.setBridgeMode(bridgeMode);// Tell JS the bridge secret.int secret = generateBridgeSecret();return ""+secret;} else {LOG.e(LOG_TAG, "gap_init called from restricted origin: " + origin);}return "";}return null;}
到这里整个流程又衔接上了,就不在废话了
这篇关于Cordova源码深入分析-第五讲的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!