Плагины для BlackBerry 10
Этот раздел содержит сведения о том, как реализовать код родной плагин на платформе BlackBerry 10. Прежде чем читать это, прочтите секции "Архитектура плагинов" для обзор структуры плагина и его общего JavaScript интерфейса. Этот раздел продолжает демонстрировать образец плагина echo, который взаимодействует с WebView Cordova на стороне платформы и наоборот.
Плагин Echo просто возвращает любую строку, которую функция window.echo
отправляет из JavaScript:
window.echo = function(str, callback) {
cordova.exec(callback, function(err) {
callback('Nothing to echo.');
}, "Echo", "echo", [str]);
};
Cordova плагин для BlackBerry 10 содержит как JavaScript так и код платформы, которые общаются друг с другом через фреймворк, предоставляемый JNEXT. Каждый плагин должен также включать файл plugin.xml
.
Создание класса плагина
Для создания основной части вашего плагина, откройте BlackBerry 10 NDK IDE и выберите File → New → BlackBerry Project → Native Extension → BlackBerry 10. Введите нужное имя и расположение проекта, затем нажмите кнопку Finish.
Проект, созданный в среде IDE содержит примеры кода для плагина памяти. Вы можете перезаписать или изменить эти файлы для реализации собственного функционала:
*name*_js.hpp
: Заголовок C++ для кода JNEXT.*name*_js.cpp
: Код C++ для JNEXT.
Родной интерфейс для модуля JNEXT может быть просмотрен в файле заголовка плагина, расположенном в каталоге public проекта. К вашим услугам также константы и сервисных функций, доступных из кода платформы. Плагин должен быть производным от класса JSExt
, который определен в plugin.h
. То есть необходимо реализовать следующий класс:
class JSExt
{
public:
virtual ~JSExt() {};
virtual string InvokeMethod( const string& strCommand ) = 0;
virtual bool CanDelete( void ) = 0;
private:
std::string m_id;
};
Плаин должн включать заголовочный файл plugin.h
. В примере Echo
, вы используете JSExt
как указано в следующем echo_js.hpp
файле:
#include "../public/plugin.h"
#include <string>
#ifndef ECHO_JS_H_
#define ECHO_JS_H_
class Echo : public JSExt
{
public:
explicit Echo(const std::string& id);
virtual ~Echo();
virtual std::string InvokeMethod(const std::string& command);
virtual bool CanDelete();
private:
std::string m_id;
};
#endif // ECHO_JS_H_
m_id
атрибут содержит JNEXT
id для объекта, который передается в класс в качестве аргумента конструктора. Он необходим для стороны платформы чтобы вызывать события на стороне JavaScript. Метод CanDelete
определяет, может ли быть удален объект определенный на строне платформы. Функция InvokeMethod
вызывается в результате запроса со стороны JavaScript для вызова метода из данного конкретного объекта. Единственный аргумент этой функции является строка, передаваемая из JavaScript, который анализируется этим методом для определения, какой из методов собственного объекта должен быть выполнен. Эти методы реализуются в echo_js.cpp
. Вот функция InvokeMethod
для Echo
:
string Echo::InvokeMethod(const string& command) {
//parse command and args from string
int index = command.find_first_of(" ");
string strCommand = command.substr(0, index);
string strValue = command.substr(index + 1, command.length());
// Determine which function should be executed
if (strCommand == "echo") {
return strValue;
} else {
return "Unsupported Method";
}
}
Плагин платформы должен также реализовывать следующие функции обратного вызова:
extern char* onGetObjList( void );
extern JSExt* onCreateObject( const string& strClassName, const string& strObjId );
Функция onGetObjList
возвращает разделенный запятыми список классов, поддерживаемых JNEXT. JNEXT использует эту функцию для определения набора классов, которые могут быть созданы JNEXT. Плагин Echo
реализует следующе в echo_js.cpp
:
char* onGetObjList() {
static char name[] = "Echo";
return name;
}
Функция onCreateObject
принимает два параметра. Первый, это имя запрашиваемого класса который должен быть создан для стороны JavaScript, с допустимыми именами как те которые были возвращены из onGetObjList
. Вторым параметром является уникальный идентификатор объекта класса. Этот метод возвращает указатель на созданный объект плагина. Плагин Echo
реализует следующе в echo_js.cpp
:
JSExt* onCreateObject(const string& className, const string& id) {
if (className == "Echo") {
return new Echo(id);
}
return NULL;
}
Создание плагина JavaScript
Плагин должен содержать следующие файлы JavaScript:
client.js
: Это файл считается клиентской стороной и содержит API для Cordova-приложения. API в вызовахclient.js
делает вызовы кindex.js
. API вclient.js
также связывает функции обратного вызова с событиями, которые вызывают эти функции.index.js
: Cordova загружаетindex.js
и делает его доступным через шлюз cordova.exec. Файлclient.js
делает вызовы к API в файлеindex.js
, который в свою очередь делает вызов к JNEXT для взаимодействия со стороной платформы.
Стороне клиента и сервера (client.js
и index.js
) взаимодействует через функцию cordova.exec
. Файлу client.js
нужно вызывать функцию exec
и предоставить необходимые аргументы. Плагин Echo
реализует следующее в файле client.js
:
var service = "org.apache.cordova.blackberry.echo",
exec = cordova.require("cordova/exec");
module.exports = {
echo: function (data, success, fail) {
exec(success, fail, service, "echo", { data: data });
}
};
Компонент index.js
использует JNEXT для взаимодействия со стороной платформы. Присоединение функции конструктора с именем Echo
к JNEXT позволяет выполнять следующие основные операции с помощью функции init
:
Укажите необходимый модуль, экспортируемые со стороны платформы. Имя необходимого модуля должно соответствовать имени файла общей библиотеки (
.so
файл):JNEXT.require("libecho")
Создайте объект используя полученный модуль и сохраните идентификатор, который был возвращен:
self.m_id = JNEXT.createObject("libecho.Echo");
Когда приложение вызывает функцию
echo
изclient.js
, которая в свою очередь, вызывает функциюecho
изindex.js
, откуда объектPluginResult
отправляет данные как ответ обратно вclient.js
. Так как аргументargs
, передаваемый в функции был преобразован с помощьюJSON.stringfy()
и закодирован какURIcomponent
, вам необходимо вызвать следующее:data = JSON.parse(decodeURIComponent(args.data));
Теперь вы можете отправить данные обратно, как показано ниже:
module.exports = {
echo: function (success, fail, args, env) {
var result = new PluginResult(args, env),
data = JSON.parse(decodeURIComponent(args.data)),
response = echo.getInstance().echo(data);
result.ok(response, false);
}
};
Архитектура плагинов
Вы можете разместить артефакты плагина, включая файл plugin.xml
, исходные файлы JavaScript и C++ и двоичные файлы .so
в любой структуре каталогов, до тех пор, пока вы правильно указываете расположение файлов в файле plugin.xml
. Вот типичная структура:
project_directory (раздел настроек plugin.xml)
- www (>client.js)
- src
- blackberry10 (>index.js, native >*.cpp, *.hpp)
- device (>двоичный файл * .so)
- simulator (>двоичный файл * .so)
В списке отображаются иерархические отношения между каталогами верхнего уровня. Скобки показывает содержимое данного каталога. Все имена каталогов отображаются полужирным шрифтом. Именам файлов предшествует знак >
.
Файл plugin.xml
Файл plugin.xml
содержит пространства имен расширения и другие метаданные. Настройте плагин Echo
следующим образом:
<plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
id="org.apache.cordova.blackberry.echo"
version="1.0.0">
<js-module src="www/client.js">
<merges target="navigator" />
</js-module>
<platform name="blackberry10">
<source-file src="src/blackberry10/index.js" />
<lib-file src="src/blackberry10/native/device/libecho.so" arch="device" />
<lib-file src="src/blackberry10/native/simulator/libecho.so" arch="simulator" />
<config-file target="www/config.xml" parent="/widget">
<feature name="org.apache.cordova.blackberry.echo" value="org.apache.cordova.blackberry.echo" />
</config-file>
</platform>
</plugin>