1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/chinasoft6_ohos-java-js-communication

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

Реализация эффекта

1. Проект

Данный проект использует функцию имитации изменения прогресса загрузки файла, чтобы продемонстрировать способность JS FA подписываться на JAVA PA. После подписки JS может постоянно получать данные о прогрессе, возвращаемые JAVA, и использовать их для обновления индикатора выполнения на интерфейсе JS. Кроме того, после завершения имитации загрузки файл переходит на страницу вычисления, где пользователь вводит два числа, а затем нажимает кнопку вычисления. В результате демонстрируется способность JS FA вызывать JAVA PA. В этом случае данные не могут быть получены постоянно, как при подписке, а только один раз за вызов.

Проект позволяет изучить следующие функции:

  • FeatureAbility.callAbility(OBJECT): вызов способности PA.
  • FeatureAbility.subscribeAbilityEvent(OBJECT, Function): подписка на события способности PA.
  • FeatureAbility.unsubscribeAbilityEvent(OBJECT): отмена подписки на события способности PA.

2. Структура кода

  1. java/ServiceAbility — код для связи между Java и JS.
  2. java-RequestParam — класс сущности запроса параметров.
  3. js-pages-index.hml — страница имитации загрузки файла в JS.
  4. js-pages-index.js — код подписки на JAVA PA в JS.
  5. js-calculate-calculate.hml — страница вычисления в JS.
  6. js-calculate-calculate.js — код вызова JAVA PA в JS.
  7. config.json — файл конфигурации для JS и Java, включая конфигурацию страниц, конфигурацию сервисов, конфигурацию окон и т. д.

3. Создание проекта JS

  1. Щёлкните правой кнопкой мыши и выберите «new» → «new project».
  2. Выберите шаблон и нажмите «next».
  3. Введите название проекта, выберите тип проекта (одиночный выбор), версию API, тип устройства и нажмите «finish».

4. Подписка на PA

  1. Нажмите кнопку загрузки, чтобы отправить запрос на подписку на Java.
/**
 * Запрос на открытие режима подписки
 */
subscribe: async function() {
    this.isShow = true; // Показать содержимое индикатора выполнения
    var that = this;

    var actionData = {};
    actionData.firstNum = that.message;

    var action = {};
    action.bundleName = 'com.example.javajscommunication'; // Имя Ability, которое должно совпадать с PA, с учётом регистра
    action.abilityName = 'com.example.javajscommunication.ServiceAbility'; // Имя Ability, которое должно совпадать с PA, с учётом регистра
    action.messageCode = ACTION_MESSAGE_CODE_PLUS_SUB; // Код операции Ability (код операции определяет бизнес-функцию PA, которая должна быть согласована с PA)
    action.data = actionData; // Данные, отправляемые в Ability, поля данных должны быть согласованы с PA
    action.abilityType = ABILITY_TYPE_EXTERNAL; // Тип Ability, соответствующий различным реализациям PA
    action.syncOption = ACTION_SYNC; // Опция синхронизации PA для обработки сообщений, 0: синхронный режим по умолчанию, 1: асинхронный режим

    await FeatureAbility.subscribeAbilityEvent(action, function (callbackData) {
        var callbackJson = JSON.parse(callbackData); // десериализация строки json
        that.message = callbackJson.data.abilityEvent;
        if (that.message == 100) { // когда message равно 100, перейти на страницу расчёта
            router.push({
                uri: "pages/calculate/calculate"
            })
            that.unsubscribe(); // Отменить подписку
            that.isShow = false; // Скрыть индикатор выполнения
        }
    })
}
  1. Java обрабатывает запрос на подписку в ServiceAbility во внутреннем классе MyRemote onRemoteRequest, определяя тип запроса на основе параметра code.
case ACTION_MESSAGE_CODE_PLUS_SUB: {
    go = true; // Разрешить загрузку
    remoteObjectHandler = data.readRemoteObject(); // Получить объект запроса
    String zsonStr = data.readString(); // Получить строку параметров

    try {
        param = ZSONObject.stringToClass(zsonStr, RequestParam.class); // Преобразовать строку объекта в экземпляр RequestParam
    } catch (RuntimeException e) {

    }
    startNotify(param); // Отправить информацию на JS

    Map<String, Object> zsonResult = new HashMap<String, Object>();// Возвращаемый результат, ключевые поля должны быть согласованы с JS
    zsonResult.put("code", SUCCESS);
    reply.writeString(ZSONObject.toZSONString(zsonResult)); // Преобразование карты в строку json и возврат к JS
    return true;
}
  1. Java запускает поток, который отправляет данные на JS каждые 15 миллисекунд с частотой 5 * 3. Здесь данные, отправленные Java на JS, будут получены через функцию обратного вызова подписки Java PA. Получение текущего значения прогресса из запроса
new Thread(() -> { // 开启线程
    while (go) {
        try {
            Thread.sleep(5 * 3); // 线程睡眠15毫秒后继续往下执行
            MessageParcel data = MessageParcel.obtain(); // 创建索引为0的空MessageParcel对象
            MessageParcel reply = MessageParcel.obtain();
            zsonEvent.put("abilityEvent", number++);
            if (number == 101) { // number超过100 go状态设为false 下载结束
                go = false;
            }
            data.writeString(ZSONObject.toZSONString(zsonEvent)); // 数据存到MessageParcel载体
            remoteObjectHandler.sendRequest(100, data, reply, option); // 发送
            reply.reclaim(); // 回收
            data.reclaim();
        } catch (RemoteException | InterruptedException e) {
            break;
        }
    }
}).start();

Отмена подписки на js-странице и остановка возврата данных с java-сервера

Js-код:

/**
 * Запрос отмены подписки, java-сервер прекращает возврат данных
 */
unsubscribe: async function() {
    var action = {};
    action.bundleName = 'com.example.javajscommunication'; // Ability's package name, needs to match PA, case sensitive
    action.abilityName = 'com.example.javajscommunication.ServiceAbility'; // Ability name, needs to match PA, case sensitive
    action.messageCode = ACTION_MESSAGE_CODE_PLUS_UNSUB; // Ability operation code (operation code defines PA's business functionality, needs to be agreed with PA)
    action.abilityType = ABILITY_TYPE_EXTERNAL; // Ability type, corresponds to different implementation methods on PA
    action.syncOption = ACTION_SYNC;  // PA side request message processing sync/async option 0: sync mode, default mode. 1: async mode

    var result = await FeatureAbility.unsubscribeAbilityEvent(action); // Отменить подписку
    var ret = JSON.parse(result); // Десериализация
    if (ret.code == 0) {
        prompt.showToast({
            message: 'Отмена загрузки прошла успешно'
        })
    } else {
        prompt.showToast({
            message: 'Ошибка при отмене загрузки'
        })
    }
}

Java-код сервера:

case ACTION_MESSAGE_CODE_PLUS_UNSUB: {
    go = false; // Остановка цикла while в методе startNotify, прекращение отправки сообщений на js
    Map<String, Object> zsonResult = new HashMap<String, Object>();
    zsonResult.put("code", SUCCESS);
    reply.writeString(ZSONObject.toZSONString(zsonResult)); // Ответ на js
    return true;
}

Вызов PA для интерпретации

  1. Получение входных значений, которые передаются с js-страницы.
 /** 
  * Получить переданное первое значение 
  */
    numOne (e){
        this.numOne = e.value
    },  
 /** 
  * Получение переданного второго значения
  */
    numTwo (e){
        this.numTwo = e.value
    }
  1. Отправка запроса на вызов при нажатии кнопки «Вычислить».
calculate: async function() {
    var actionData = {}; // key values correspond to RequestParam class members on PA
    actionData.firstNum = this.numOne;
    actionData.secondNum = this.numTwo;

    var action = {};
    action.bundleName = 'com.example.javajscommunication'; // Ability's package name, needs to match PA, case sensitive
    action.abilityName = 'com.example.javajscommunication.ServiceAbility'; // Ability name, needs to match PA, case sensitive
    action.messageCode = ACTION_MESSAGE_CODE_PLUS; // Ability operation code (operation code defines PA's business functionality, needs to be agreed with PA)
    action.data = actionData; // Data sent to Ability, data field names need to be agreed with PA
    action.abilityType = ABILITY_TYPE_EXTERNAL; // Ability type, corresponds to different implementation methods on PA
    action.syncOption = ACTION_SYNC;  // PA side request message processing sync/async option 0: sync mode, default mode. 1: async mode

    var result = await FeatureAbility.callAbility(action);
    var ret = JSON.parse(result);
    if (ret.code == 0) {
        this.message =  'Java-сервер вернул данные:' + JSON.stringify(ret.abilityResult);
    } else {
        this.message =  'Ошибка в данных, возвращённых java-сервером' + JSON.stringify(ret.code);
    }
},
  1. Обработка запросов на подписку на сервере Java в классе ServiceAbility, где в методе onRemoteRequest класса MyRemote происходит обработка запросов в зависимости от параметра code. Здесь данные, отправленные с Java, будут получены через вызов результатов Java PA.
case ACTION_MESSAGE_CODE_PLUS: {
    String zsonStr = data.readString(); // Получение строки параметров
    RequestParam param = new RequestParam();
    try {
        param = ZSONObject.stringToClass(zsonStr, RequestParam.class); // Преобразование строки в экземпляр RequestParam
    } catch (RuntimeException e) {

    }

    // Возвращаемые данные поддерживают только сериализуемые типы объектов
    Map<String, Object> zsonResult = new HashMap<>();
    zsonResult.put("code", SUCCESS);
    zsonResult.put("abilityResult", param.getFirstNum() + " * " + param.getSecondNum() + " = " + (param.getFirstNum() * param.getSecondNum()));
    reply.writeString(ZSONObject.toZSONString(zsonResult)); // Данные возвращаются на js
    return true;
}
  1. Возврат к предыдущей странице, здесь в коде js импортируется router. Из '@system.router', затем используя связанные методы объекта router, вернуться.
back(){
    router.back() // Вернуться на предыдущую страницу
}

Код можно посмотреть по ссылке:
https://gitee.com/chinasoft6_ohos/java-js-communication

Автор: Цзинь Гоцзюнь

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Пример вызова Java PA из JS FA. Развернуть Свернуть
Apache-2.0
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/chinasoft6_ohos-java-js-communication.git
git@api.gitlife.ru:oschina-mirror/chinasoft6_ohos-java-js-communication.git
oschina-mirror
chinasoft6_ohos-java-js-communication
chinasoft6_ohos-java-js-communication
master