Cordova插件 - 回调只执行一次

时间:2016-03-31 09:01:50

标签: javascript windows cordova bluetooth callback

我正在尝试使用必需的代码更新BluetoothSerial cordova plugin以使用Windows Universal运行。不幸的是,我无法找到解决以下问题的方法。

假设我想通过蓝牙将智能手机连接到另一个使用串行端口的蓝牙设备。很明显,首先要做的是调用插件的connect方法,它将初始化 writer reader ,并且还将启动异步读取循环,由函数 receiveStringLoop 提供。另一个蓝牙设备不断发送数据,因此我想将我的手机订阅到该蓝牙设备,这意味着我的应用程序将在到达时自动处理传入的数据。这是应用程序代码的极其简化版本。

ns.connect = function (event) {
    var device = event.target.getAttribute("did");
    bluetoothSerial.connect(device, led.onconnect, led.ondisconnect);
}

ns.onconnect = function() {
    var success = function (data) {
        console.log("Success receiving subscribed data: " + data);
    };

    var failure = function () {
        console.log("Failed to receive...");
    };

    bluetoothSerial.subscribe('\n', success, failure);
}

ns.ondisconnect = function(err) {
    console.log(err);
}

让我们看一下插件代码。由于代码很长,让我发帖the link to it。当调用 subscribe 方法时,插件将存储分隔符(用于分隔两个不同传入消息的字符)和成功回调。如果插件中的数据为红色,并且 subscribe 被普遍调用,那么插件将执行成功回调,发送回数据。

receiveStringLoop: function(reader) {
        // Read first byte (length of the subsequent message, 255 or less). 
        reader.loadAsync(1).done(function (size) {      
            if (size != 1) {
                bluetoothSerial.disconnect();
                console.log("The underlying socket was closed before we were able to read the whole data. Client disconnected.", "sample", "status");
                return;
            }

            // Read the message. 
            var messageLength = reader.readByte();
            console.log("messageLength: " + messageLength);

            reader.loadAsync(messageLength).done(function(actualMessageLength) {
                if (messageLength != actualMessageLength)
                {
                    // The underlying socket was closed before we were able to read the whole data. 
                    console.log("The underlying socket was closed before we were able to read the whole data.", "sample", "status");
                    return;
                }

                var message = reader.readString(actualMessageLength);                   
                console.log("Message readed: " + message + " - Length: " + message.length);
                buffer = message;

                if (subscribeCallback && typeof(subscribeCallback) !== "undefined") {
                    var tmp = readUntil(delimiter);
                    console.log("Data to send to subscriber: " + tmp);

                    subscribeCallback(tmp);
                }

                WinJS.Promise.timeout().done(function () { return module.exports.receiveStringLoop(reader); });
            }, function (error) {
                console.log("loadAsync -> Failed to read the message, with error: " + error, "sample", "error");
            });
        }, function (error) {
            console.log("Failed to read the message size, with error: " + error, "sample", "error");
        });
    },

问题 subscribeCallback 仅在第一次正确执行时(当第一条消息到达时,它将通过回调打印到日志中)。接下来,控制台日志显示每次消息到达时都会调用 subscribeCallback ,但由于某种原因,它不会打印传入的消息。

请,我需要帮助来弄清楚发生了什么。

1 个答案:

答案 0 :(得分:0)

我终于找到了解决方案,感谢this blog post

我写这篇文章是希望它对其他人有用。默认情况下,Cordova不允许多次调用成功回调。在其他平台(Android,iOS)上,可以通过将PluginResult对象的属性setKeepCallbackAsBool(或KeepCallback)设置为true来强制Cordova。当您为Windows Universal开发插件(使用javascript)时,没有PluginResult对象。解决方法是将回调作为附加参数传递。让我发布一个代码来解释。

这是一段没有myPluginFolder / www / myPlugin.js文件解决方法的代码

subscribe: function (delimiter, success, failure) {
    cordova.exec(success, failure, "BluetoothSerial", "subscribe", [delimiter]);
}

这是myPluginFolder / src / windows / MyPlugin.js文件的相关代码段

subscribe: function(success, failure, args) {
    delimiter = args[0];
    subscribeCallback = success;
}

在这种情况下,subscribeCallback只会执行一次。现在让我发布解决方法代码:

这是myPluginFolder / www / myPlugin.js文件的一段代码

subscribe: function (delimiter, success, failure) {
    cordova.exec(success, failure, "BluetoothSerial", "subscribe", [delimiter, success]);
}

注意我是如何将成功回调放入数组参数中的。这是文件myPluginFolder / src / windows / MyPlugin.js的相关代码段

subscribe: function(success, failure, args) {
    delimiter = args[0];
    subscribeCallback = args[1];
}

通过这种解决方法,我终于可以根据需要多次调用subscribeCallback。