Cordova multiple callbacks in Windows Phone 8

你。 提交于 2019-12-11 02:36:46

问题


I have a Cordova plugin which works fine for both Android & iOS. However, it fails when ported to Windows Phone 8 because it seems that multiple outstanding callbacks are not supported in Cordova for Windows Phone.

The problem is this:

When a DispatchCommandResult is called with a PluginResult which has KeepCallback set to true, a further DispatchCommand from a different method will call both its callback and the previous callback (the one with KeepCallback set to true).

Worse still, if the second DispatchCommandResult has a PluginResult which has KeepCallback set to false (the default) then this cancels any further callbacks which have KeepCallback set to true.

Example:

Consider the code below. It's a modification of the Cordova Echo sample.

The echo method will (via DispatchCommandResult) call the javascript 'success' callback with the same string which it was originally called with (after a couple of JSON conversions)

The repeat method does the same as echo except it repeatedly calls the javascript 'success' callback every 5 seconds in a separate thread.

If repeat is called and then at some point after echo is called, the DispatchCommandResult in the echo method will result in both the echo success and the repeat success callbacks being called and then prevent further repeat success callbacks because the KeepCallback was not set to true.

In Android this problem is not an issue because of the callbackId provided by Cordova. However, for Windows Phone, the callbackId is not accessible.

C# code

namespace Cordova.Extension.Commands
{
    public class Echo : BaseCommand
    {
        public void echo(string options)
        {
            string optVal = JsonHelper.Deserialize<string[]>(options)[0];
            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, optVal));
        }
        public void repeat(string options)
        {
            string optVal = JsonHelper.Deserialize<string[]>(options)[0];
            ThreadStart worker = () =>
            {
                try
                {
                    while (true)
                    {
                        Thread.Sleep(5000);
                        PluginResult r = new PluginResult(PluginResult.Status.OK, optVal);
                        r.KeepCallback = true;
                        DispatchCommandResult(r);
                    }
                }
                catch (Exception ex)
                {
                    this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ex.Message));
                }
            };
            new Thread(worker).Start();
        }
    }
}

JavaScript code

function echo() {
    function success(message) {
        console.log("echo success: " + message);
    }
    function error(e) {
        console.log("echo error: " + e);
    }
    cordova.exec(success, error, "Echo", "echo", ["Hello"]);
}

function repeat() {
    function success(message) {
        console.log("repeat success: " + message);
    }
    function error(e) {
        console.log("repeat error: " + e);
    }
    cordova.exec(success, error, "Echo", "repeat", ["Hello again"]);
}

echo();
.
.
.
repeat();
.
.
.
echo();

Sample output

Log:"echo success: Hello"
Log:"repeat success: Hello again"
Log:"repeat success: Hello again"
Log:"repeat success: Hello again"
Log:"repeat success: Hello again"
Log:"repeat success: Hello"
Log:"echo success: Hello"

Has anyone else had this problem? If so, is there a workaround? Am I doing anything wrong?


回答1:


I had the same problem with cordova 2.5 and this is what I found.

In the (not yet released) 2.8 version of cordova, if you look at the BaseCommand.cs of the cordovalib files. You can see a CurrentCommandCallbackId that can be used to keep track of the callback you want to call.

Then if you set the KeepCallback to false, you can dispatch the command to the wanted callback.

The current release of PhoneGap is the 2.7.0, so to use this you'll have to clone the 2.8 version of cordova and copy the content of Plugins, cordova and cordivalib of the templates/standalone folder.

Once done, you can use this new feature with something like:

private void DispatchMessage(PluginResult.Status status, string message, bool keepCallback, string callBackID)
{
    PluginResult res = new PluginResult(status, message);
    res.KeepCallback = keepCallback;
    DispatchCommandResult(res, callBackID);
}

However, once Phonegap 2.8 will be release, it will be safer to update your App with an official version of Cordova.



来源:https://stackoverflow.com/questions/14757212/cordova-multiple-callbacks-in-windows-phone-8

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!