PhoneGap的js回调有几种实现方式。其中一种是ajax。

我们先来看一下js端相关代码:

// file: lib/android/plugin/android/callback.jsdefine("cordova/plugin/android/callback", function(require, exports, module) {var port = null,    token = null,    xmlhttp;function startXhr() {    // cordova/exec depends on this module, so we can't require cordova/exec on the module level.    var exec = require('cordova/exec'),    xmlhttp = new XMLHttpRequest();    // Callback function when XMLHttpRequest is ready    xmlhttp.onreadystatechange=function(){        if (!xmlhttp) {            return;        }        if (xmlhttp.readyState === 4){            // If callback has JavaScript statement to execute            if (xmlhttp.status === 200) {                // Need to url decode the response                var msg = decodeURIComponent(xmlhttp.responseText);                setTimeout(startXhr, 1);                exec.processMessages(msg);            }            // If callback ping (used to keep XHR request from timing out)            else if (xmlhttp.status === 404) {                setTimeout(startXhr, 10);            }            // 0 == Page is unloading.            // 400 == Bad request.            // 403 == invalid token.            // 503 == server stopped.            else {                console.log("JSCallback Error: Request failed with status " + xmlhttp.status);                exec.setNativeToJsBridgeMode(exec.nativeToJsModes.POLLING);            }        }    };    if (port === null) {        port = prompt("getPort", "gap_callbackServer:");    }    if (token === null) {        token = prompt("getToken", "gap_callbackServer:");    }    xmlhttp.open("GET", "http://127.0.0.1:"+port+"/"+token , true);    xmlhttp.send();}module.exports = {    start: function() {        startXhr();    },    stop: function() {        if (xmlhttp) {            var tmp = xmlhttp;            xmlhttp = null;            tmp.abort();        }    },    isAvailable: function() {        return ("true" != prompt("usePolling", "gap_callbackServer:"));    }};});

主要的处理是startXhr函数。它向java的server端发起了ajax请求,在onreadystatechange这个回调函数中等待server端返回结果。如果server端返回的结果正确,则再通过setTimeout(startXhr, 1)函数,1豪秒后再重新向server端发起ajax请求。如果从server返回的结果状态是404,则每隔10豪秒,重新向server端发起ajax请求。

接下来看看server端是如何处理的。server端的处理代码是CallbackServer.java中的run()方法中。

先看server端的源码:

它通过serverSocket来模拟http的server端。其中,jsMessageQueue中是从java端发送的js消息,serverSocket在接收到客户端(js端)的请求后,会将jsMessageQueue中的js代码发送到客户端(js端)。

    /**     * Start running the server.       * This is called automatically when the server thread is started.     */    public void run() {        // Start server        try {            this.active = true;            String request;            waitSocket = new ServerSocket(0);            this.port = waitSocket.getLocalPort();            //Log.d(LOG_TAG, "CallbackServer -- using port " +this.port);            this.token = java.util.UUID.randomUUID().toString();            //Log.d(LOG_TAG, "CallbackServer -- using token "+this.token);            while (this.active) {                //Log.d(LOG_TAG, "CallbackServer: Waiting for data on socket");                Socket connection = waitSocket.accept();                BufferedReader xhrReader = new BufferedReader(new InputStreamReader(connection.getInputStream()), 40);                DataOutputStream output = new DataOutputStream(connection.getOutputStream());                request = xhrReader.readLine();                String response = "";                //Log.d(LOG_TAG, "CallbackServerRequest="+request);                if (this.active && (request != null)) {                    if (request.contains("GET")) {                        // Get requested file                        String[] requestParts = request.split(" ");                        // Must have security token                        if ((requestParts.length == 3) && (requestParts[1].substring(1).equals(this.token))) {                            //Log.d(LOG_TAG, "CallbackServer -- Processing GET request");                        String payload = null;                            // Wait until there is some data to send, or send empty data every 10 sec                             // to prevent XHR timeout on the client                             while (this.active) {                            if (jsMessageQueue != null) {                            payload = jsMessageQueue.popAndEncode();                                if (payload != null) {                                break;                                }                            }                            synchronized (this) {                                    try {                                        this.wait(10000); // prevent timeout from happening                                        //Log.d(LOG_TAG, "CallbackServer>>> break <<<");                                        break;                                    } catch (Exception e) {                                    }                                }                            }                            // If server is still running                            if (this.active) {                                // If no data, then send 404 back to client before it times out                                if (payload == null) {                                    //Log.d(LOG_TAG, "CallbackServer -- sending data 0");                                    response = "HTTP/1.1 404 NO DATA\r\n\r\n "; // need to send content otherwise some Android devices fail, so send space                                }                                else {                                    //Log.d(LOG_TAG, "CallbackServer -- sending item");                                    response = "HTTP/1.1 200 OK\r\n\r\n";                                    response += encode(payload, "UTF-8");                                }                            }                            else {                                response = "HTTP/1.1 503 Service Unavailable\r\n\r\n ";                            }                        }                        else {                            response = "HTTP/1.1 403 Forbidden\r\n\r\n ";                        }                    }                    else {                        response = "HTTP/1.1 400 Bad Request\r\n\r\n ";                    }                    //Log.d(LOG_TAG, "CallbackServer: response="+response);                    //Log.d(LOG_TAG, "CallbackServer: closing output");                    output.writeBytes(response);                    output.flush();                }                output.close();                xhrReader.close();            }        } catch (IOException e) {            e.printStackTrace();        }        this.active = false;        //Log.d(LOG_TAG, "CallbackServer.startServer() - EXIT");    }

更多相关文章

  1. C语言函数以及函数的使用
  2. Android 实现蓝牙客户端与服务器端通信
  3. 《第一行代码——Android》
  4. Android SDK 源代码编译
  5. android布局实例代码
  6. Android手机客户端与Servlet交换数据
  7. 第一行代码Android第三课
  8. Android 开源源代码收集(不断更新中...)
  9. Android顶部工具栏和底部工具栏的简单实现代码

随机推荐

  1. Android(安卓)HTTP 压缩 gzip
  2. Android用Apache HttpClient 实现POST和G
  3. Android打开应用市场
  4. android监听网络变化
  5. Intent在android中的几种用法
  6. android与h5简单交互(js调取android的拨打
  7. 收藏代码-Android状态栏工具代码
  8. Android(安卓)onSensorChanged 水平感应(T
  9. Gps简单更新
  10. Android(安卓)Studio 搭建 + 第一个hello