android QuickConnect框架使用

在导师的帮助下,我终于看懂了一点QC啦!


QC是一个利用JS与java相互调用的框架。他的好处在于你可以不用android的UI显示界面,用js来显示界面。

这个框架是用来扩展你的js调用android系统功能的,说白了就是可以从js端直接调用android的功能,方便大家一起扩展js调用java的功能。其实质就是android端在调用相应API来完成一些功能,只不过与js之间相互交换一些参数罢了。


怎样在QC中扩展自己的功能

JS端 asset文件夹

1.发送请求handleRequest('browseFileJS','/sdcard/');

这个函数是开始执行框架的入口函数。handleRequest()的第一个参数是命令,第二个参数是命令的参数,即发送给java端BCO.java与VCO.java的参数。

2.asset/mappings.js

框架启动时会首先在mappings.js中映射JS端的请求命令与BCF与VCF函数进行映射

    mapCommandToBCF('browseFileJS',changeTextBCF);
    mapCommandToVCF('browseFileJS',changeTextVCF);

这两句话要在你发送JS请求命令之前写上。即你要在发送JS请求命令之前要把命令跟相关的BCF与VCF映射好,不然在你发送命令的时候,框架找不到相应的调用函数

3.asset/ function.js

这个js文件中写你自己的BCF与VCF函数

 

function browseFileBCF(parameters){

//parameters是你从JS端发送请求时附带的参数
    pg_log.Debug("function.js:[browseFileBCF]");
    browseFile(parameters);
    document.getElementById('coco').innerText = '/sdcard/';
}

 

function browseFileVCF(data, param){                      

//data[0]是你从java端的VCO.java中的JSONArray中push进的第一个参数,即你要从java端返回给JS端的参数。

//param是你从JS端发送请求时附带的参数,与BCF中的parameters是同一个值

    pg_log.Debug("function.js:[browseFileVCF]");
    var returnFromJavaToJs=data[0]; 
    var p2=param;
    var s=new String();
    for(var i=0;i<returnFromJavaToJs.length;i++){
        var f=returnFromJavaToJs[i];
        s=s+'/n'+f.type+'  '+f.name;
    }
    document.getElementById('coco').innerText =p2+s;
}

4.asset/ QCAndroid/com.js

这个js文件中是写你自定义BCF与VCF函数需要调用到的函数。你也可以往这个js文件中写函数,直接在BCF与VCF函数中完成你想写的功能

 

function browseFile(parameters){
    var dataArray = new Array();
    var callBackParameters = generatePassThroughParameters();
    dataArray.push(parameters);
    dataArray.push(callBackParameters);
    var dataString = JSON.stringify(dataArray);
    pg_log.Debug("com.js:[browseFile]:"+dataString);
    makeCall("browseFileJava", dataString);
    return null;   
}

1)有关回调函数VCF地址

generatePassThroughParameters()函数返回你自定义的VCF函数的回调地址。这个框架是这么个流程。从handleRequest发送命令与参数给Java端开始。js端调用BCF函数,BCF发送命令与参数给Java端,并且把VCF的回调地址也带给java端。然后java端调用BCO.java的handleIt()函数,BCO.java再把返回结果与原始参数传递给VCO.java函数,然后VCO.java把需要返回给JS端的参数和js端传递过来的VCF函数的回调地址再传回给JS端。

我开始也很奇怪为什么VCF回调函数的地址要传给Java又传回JS。

在导师的说明下,我明白啦!

这个框架中,一个是发送的装配车间,一个是回收结果的装配车间。即装配BCF与VCF。

当出装配车间的时候,他可以直接装配出 回调函数(参数) ,而不用再去很麻烦的去找对应的回调函数地址。因为这在之前已经map过acmd与VCF了。有人说,在之前map,与出装配车间后再map有什么区别呢。可能是为了框架的工整性着想。因为一气儿把BCF与VCF全部map完了就显得整个框架很工整,容易懂。不然某个地方map BCF,某个地方map VCF ,会造成混乱。

2)有关makeCall("browseFileJava", dataString)

我们来看下makeCall函数定义

 

asset/QCAndroid/com.js

function makeCall(command, dataString){
    if(command){
        qcDevice.makeCall(command, dataString);
    }
}

我们来看下Java端怎样向JS端嵌入对象

org.quick.connect/QuickConnectActivity.java

webView.addJavascriptInterface(new JavaScriptCallHandler(), "qcDevice");

//将JavaScriptCallHandler.java对象绑定到JS端,并且这个对象命名为"qcDevice"

webView.loadUrl("file:///android_asset/index.html");

//加载asset文件中的html网页

3)有关传递 参数的顺序问题

 

asset/QCAndroid/com.js

function browseFile(parameters){

    var dataArray = new Array() ;
    var callBackParameters = generatePassThroughParameters();
    dataArray.push(parameters);
    dataArray.push(callBackParameters);
    var dataString = JSON.stringify(dataArray);
    makeCall("browseFileJava", dataString);

}

将要附带的参数与回调地址的参数分别放到Array中,然后转换成JSON字符串,再传递给Java端就可以了。

参数顺序可以自己调整,只要你传递到Java端的BCO中或者VCO中,你自己可以对上号就可以了。

即JS端发送的是Array,Java端的BCO.java接收的是JSONArray。这两端相互对应。

 

public class BrowseFileBCO implements CommandObject {

    public Object handleIt(Object parameters) {
        Log.d("coco", "ChangeTextBCO parameters : "+parameters);
        Object fromJSParameters=null;
        try {
            fromJSParameters=((JSONArray)parameters ).get(0);

...

}

 

 

 

JAVA端 src文件夹

1.org.quick.connect/QCCommandMappings.java

Java端启动时首先也会做Java端的命令与相应BCO.java与VCO.java的映射

        QCUtilities.mapCommandToBCO("browseFileJava", BrowseFileBCO.class);
        QCUtilities.mapCommandToVCO("browseFileJava", BrowseFileVCO.class);

2.org.quick.connect.commandobjects/

写上自己的BCO.java与VCO.java文件,注意要实现CommandObject接口

 

public class BrowseFileBCO implements CommandObject {

    public Object handleIt(Object parameters) {
        Log.d("coco", "ChangeTextBCO parameters : "+parameters);
        Object fromJSParameters=null;
        try {
            fromJSParameters=((JSONArray)parameters).get(0);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        String fromJSString=(String)fromJSParameters;
       
        JSONArray resultFileLists=FileOperation.getFiles_JSONArray(fromJSString);
       
        return resultFileLists;
    }

}

 

public class BrowseFileVCO implements CommandObject{

    public Object handleIt(Object parameters) {
        Log.d("coco", "ChangeTextVCO.handleIt( "+parameters+" )");
        String callbackVCFAddr=null;
        try {
            callbackVCFAddr = (String)((JSONArray)((JSONArray)((ArrayList)parameters).get(0)).get(1)).get(0);
        } catch (JSONException e) {
            e.printStackTrace();
        }
       
        Object fromJavaBCOParams=((ArrayList)parameters).get(1);
        JSONArray fromJavaBCOJSONArray=(JSONArray)fromJavaBCOParams;   
        String toJSString="Java get from JS : "+fromJavaBCOJSONArray.toString();
        Log.d("coco", "ChangeTextVCO toJSString : "+toJSString);
        JSONArray returnValues = new JSONArray();
        returnValues.put(fromJavaBCOJSONArray);
       
        returnValues.put(callbackVCFAddr);
        String aJSONString = returnValues.toString();
        String aJSCallString = "javascript:handleRequestCompletionFromNative('"+aJSONString+"')";
        Log.d("coco", "ChangeTextVCO-aJSONString: "+aJSONString);
        QuickConnectActivity.getWebView().loadUrl(aJSCallString);
        return toJSString;
    }

}

 

3.有关BCO与VCO的参数传递问题

1)BCO.java的参数

public Object handleIt(Object parameters) {}

这里的parameters是JSONArray。他与JS端的makeCall(command, dataString)中的dataString对应。dataString前身就是Array。

所以说Java中的JSONArray与JS端的Array对应。往数组里面写回调函数的地址和其他附带参数是可以在两端协商的,只要两端对应好了就可以了。

但是注意,也就是在后面的VCO中,回调函数的地址是必须写在JSONArray的最后一个的。这个是框架规定。

2)BCO.java返回的参数怎样传递给VCO.java

org.quick.connect/

public class QuickConnect {

    public static Object handleRequest(String command, Object parameters){
        Object retVal = null;
        if(checkValidation(command, parameters)){
            ArrayList newParameters = dispatchToBCO(command, parameters);
            retVal = dispatchToVCO(command, newParameters);

...}

    private static ArrayList<Object> dispatchToHandlers(HashMap<String, ArrayList<Class> > map, String command, Object parameters){
        ArrayList<Object> resultData = new ArrayList<Object>();
        resultData.add(parameters);

                    try {
                        result = ((CommandObject)handler).handleIt(parameters);
                    }...

                if(result != null){
                    resultData.add(result);
                }

        return resultData;

...}

}

看到了吗,将BCO.java返回的参数添加到ArrayList的第二个成员中,然后将ArrayList当做参数传递给VCO.java。

即VCO.java的handleIt()参数是ArrayList。ArrayList第一个成员是BCO.java从JS端接收的JSONArray请求参数,ArrayList第二个成员是BCO.java的handleIt()函数返回的参数。

3)VCO.java怎样返回给JS端参数,以及怎样跳回JS端

public class BrowseFileVCO implements CommandObject{
    public Object handleIt(Object parameters) {

...

        String callbackVCFAddr=null;
        try {
        callbackVCFAddr = (String)((JSONArray)((JSONArray)((ArrayList)parameters).get(0)).get(1)).get(0);

        }

...

        JSONArray returnValues = new JSONArray();
        returnValues.put(fromJavaBCOJSONArray);
        returnValues.put(callbackVCFAddr);
        String aJSONString = returnValues.toString();
        String aJSCallString = "javascript:handleRequestCompletionFromNative('"+aJSONString+"')";
        Log.d("coco", "ChangeTextVCO-aJSONString: "+aJSONString);
        QuickConnectActivity.getWebView().loadUrl(aJSCallString);

...}

}

返回的JSONArray一定要这么写,第一个成员是你要返回的参数,第二个成员是回调函数VCF的地址。

我在JSONArray中的第二个成员也就是回调地址之前添加了一个成员。在VCF端,也做了相应的修改,但是调试的结果显示的是,找不到回调函数。如果发现可以修改返回的JSONArray,可以给我留言,我们交流一下哦。

4)JS端VCF接收Java端VCO.java传过来的参数

 

function browseFileVCF(data, param){                      

//data[0]是你从java端的VCO.java中的JSONArray中push进的第一个参数,即你要从java端返回给JS端的参数。

//param是你从JS端发送请求时附带的参数,与BCF中的parameters是同一个值
    var returnFromJavaToJs=data[0]; 
    var p2=param;
    var s=new String();
    for(var i=0;i<returnFromJavaToJs.length;i++){
        var f=returnFromJavaToJs[i];
        s=s+'/n'+f.type+'  '+f.name;
    }
    document.getElementById('coco').innerText =p2+s;
}

//data[0]是你从java端的VCO.java中的JSONArray中push进的第一个参数,即你要从java端返回给JS端的参数。

只有data[0]可以提取出来。也就是说你所有的从Java端VCO.java返回的参数只能存在于JSONArray的第一个成员中。第一个成员你可以写成JSONArray的形式在存放各种参数,然后从VCF中data[0]就是这个JSONArray

如果有同学发现可以写到data[1]中,欢迎给我留言或者加QQ讨论哈。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值