Множественные обратные вызовы Cordova в Windows Phone 8

У меня есть плагин Cordova, который отлично работает как для Android, так и для iOS. Однако при переносе на Windows Phone 8 происходит сбой, потому что кажется, что несколько необработанных обратных вызовов не поддерживаются в Cordova для Windows Phone.

Проблема заключается в следующем:

Когда DispatchCommandResult вызывается с PluginResult, для которого KeepCallback имеет значение true, следующий DispatchCommand из другого метода будет вызывать как свой обратный вызов, так и предыдущий обратный вызов (тот, у которого для KeepCallback установлено значение true).

Что еще хуже, если второй DispatchCommandResult имеет PluginResult, для которого KeepCallback имеет значение false (по умолчанию), то это отменяет любые дальнейшие обратные вызовы, для которых KeepCallback имеет значение true.

Пример:

Рассмотрим код ниже. Это модификация образца Cordova Echo.

Метод echo (через DispatchCommandResult) вызовет обратный вызов javascript «success» с той же строкой, с которой он был первоначально вызван (после пары преобразований JSON)

Метод повтора делает то же самое, что и эхо, за исключением того, что он повторно вызывает обратный вызов javascript «успех» каждые 5 секунд в отдельном потоке.

Если повторение вызывается, а затем в какой-то момент после вызова эха, DispatchCommandResult в методе эха приведет к вызову обоих обратных вызовов успешного эха и повторного успешного выполнения, а затем предотвратит дальнейшие обратные вызовы повторного успешного выполнения, поскольку для KeepCallback не установлено значение true.

В Android эта проблема не является проблемой из-за callbackId, предоставленного Cordova. Однако для Windows Phone callbackId недоступен.

код С#

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-код

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();

Пример вывода

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"

У кого-нибудь еще возникла такая проблема? Если да, то есть ли обходной путь? Я делаю что-то не так?


person Julian Mountford    schedule 07.02.2013    source источник
comment
ты нашел решение?   -  person Ardavan Kalhori    schedule 27.03.2013


Ответы (1)


У меня была такая же проблема с Cordova 2.5, и вот что я нашел.

В (еще не выпущенной) версии Cordova 2.8, если вы посмотрите на BaseCommand.cs файлов cordovalib. Вы можете увидеть CurrentCommandCallbackId, который можно использовать для отслеживания обратного вызова, который вы хотите вызвать.

Затем, если вы установите для KeepCallback значение false, вы можете отправить команду на требуемый обратный вызов.

Текущая версия PhoneGap — 2.7.0, поэтому для ее использования вам придется клонировать 2.8 версии Cordova и скопируйте содержимое Plugins, cordova и cordivalib папки templates/standalone.

После этого вы можете использовать эту новую функцию с чем-то вроде:

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

Однако после выхода Phonegap 2.8 будет безопаснее обновить ваше приложение до официальной версии Cordova.

person TroX    schedule 30.05.2013