8 (phonegap源码分析)JS与本地代码交互(exec )

        这里采用的是较早版本的phonegap框架中exec模块的实现,代码比较直观易懂,后来的版本为了提升代码的健壮性,增加了很多选择性代码。为了测试方便,直接使用简单版本的exec模块。更高版本的phonegap库也是在这个基础之上扩展的,可对比学习。

define("myphonegap/exec", function(require, exports, module) {
		 /**
		  * 执行cordova命令
		  * 同步:返回一个JSON字符串;异步:返回空字符串"",这个时候可以根据处理结果调用回调函数
		  * 参数:(1)success:命令执行成功回调函数
		  *       (2)fail:命令执行失败回调函数
		  *       (3)service:使用的服务名称
		  *       (4)action:在cordova中运行的命令
		  *       (5)args:0或多个参数组成的数组
		  */
		var myphonegap= require('myphonegap');

		module.exports = function(success, fail, service, action, args) {
			try {
				var callbackId = service + cordova.callbackId++;//内部回调id
				if (success || fail) {//至少传入了其中一个
					myphonegap.callbacks[callbackId] = {success:success, fail:fail};
				}

			  //将参数转化为JSON字符串去执行
				var r = prompt(JSON.stringify(args), "gap:"+JSON.stringify([service, action, callbackId, true]));
				
				if (r.length > 0) {
					var v = JSON.parse(r);//将返回结果解析成对象
					if (v.status === myphonegap.callbackStatus.OK) {
						if (success) {//调用成功回调函数
							try {
								success(v.message);
							} catch (e) {
								console.log("Error in success callback: " + callbackId  + " = " + e);
							}

							// 清除回调函数
							if (!v.keepCallback) {
								delete myphonegap.callbacks[callbackId];
							}
						}
						return v.message;
					}
					else if (v.status === myphonegap.callbackStatus.NO_RESULT) {
						// 清除回调函数
						if (!v.keepCallback) {
							delete myphonegap.callbacks[callbackId];
						}
					}
					else {// 错误
						console.log("Error: Status="+v.status+" Message="+v.message);

						// 调用失败回调函数
						if (fail) {
							try {
								fail(v.message);
							}
							catch (e1) {
								console.log("Error in error callback: "+callbackId+" = "+e1);
							}

							//清除回调函数
							if (!v.keepCallback) {
								delete myphonegap.callbacks[callbackId];
							}
						}
						return null;
					}
				}
			} catch (e2) {
				console.log("Error: "+e2);
			}
		};

	});

        这里最重要的一个函数是window提供的prompt这个函数,它实际上就是用来与android的交互的。当js调用prompt之后,本地代码WebChromeClient实例会回调一个onJsPrompt函数,在这个回调函数中接受js发送过来的参数信息,调用相应的serviceaction,同步的话直接返回结果,用result.confirm提交。异步调用,在调用结果返回之后,以回调ID和返回数据为参数,调用myphonegap.callbackSuccess或myphonegap.callbackError

        下面测试测试本地代码和JS代码的交互,由本地代码调用exec模块,给本地代码发送消息,本地代码解析消息调用对应的方法,返回结果后。

        Js端添加测试代码,先请求exec模块。第一个请求执行的本地方法,类名为Math,方法名为plus,参数为15,成功后打印输出结果。第二个请求执行的本地方法,类名为Math,方法名为multiply,参数为15

//测试exec模块
	
var exec = require("myphonegap/exec");
	exec(function(ret){console.info("plus exec success!");console.info("15+15=" + ret)}, 
				function(){console.info("multiply exec failed!")}, 'Math', 'plus',15);
				
	exec(function(ret){console.info("multiply exec success!");console.info("15*15=" + ret)}, 
			function(){console.info("multiply exec failed!")}, 'Math', 'multiply',15);

Js执行prompt方法后,androidWebChromeClientonJsPrompt被调用,为了测试简单这里只用了action区分调用的本地方法没有使用service区分调用哪个类,plus操作为同步方法,直接返回,multiply模拟为异步方法,通过回调js里面的方法返回结果。

private class MyWebChromeClient extends WebChromeClient{
		@Override
		public boolean onJsPrompt(WebView view, String url, String message,
				String defaultValue, JsPromptResult result) {
		
try {
              //array的解析与js端的封装有关,字串过滤了”gap:”4个字符
		        JSONArray array = new JSONArray(defaultValue.substring(4));
		        String service = array.getString(0);
		        String action = array.getString(1);
		        String callbackId = array.getString(2);
		        
		        if(action.equals("plus")){
		        	int a = Integer.parseInt(message);
		        	int ret = plus(a,a);
		        	String str = "{\"status\":1,\"message\":" ;
		        	    str += ret;
		        		str += "}";
		        			
		        	result.confirm(str);
		        }else if(action.equals("multiply")){
		        	int a = Integer.parseInt(message);
		        	int ret = multiply(a,a);
		        	String str = "{\"status\":1,\"message\":" ;
		        	    str += ret;
		        		str += "}";
		        			
		        	result.confirm("");
		        	//此处采用异步模式,不使用result.confirm直接返回结果了。
		            	mWebView.loadUrl("javascript:myphonegap.callbackSuccess(\""+callbackId+"\","+str+")");
		        }
		       
		      } catch (JSONException e) {
		        e.printStackTrace();
		      }
						return true;
		}

本次测试采用了android真机测试。测试结果:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值