Делегировать преобразование текста в "плагины" приложений для Android, не известных заранее

Контекст

Наше приложение показывает пользователю флеш-карту HTML.
Мы добавили несколько слоев "фильтров" для удовлетворения различных групп пользователей:

  • Чтобы удовлетворить энтузиастов chess, мы конвертируем любой блок {FEN:rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2} в таблицу HTML, представляющую шахматную доску с фигурами в правильной позиции.
  • Чтобы удовлетворить китайский язык, мы преобразуем в <ruby>字<rt>zì</rt></ruby>
  • ...

Оригинальный HTML → Шахматная трансформация → Китайская трансформация →... → Окончательный HTML для отображения

Проблема

Число фильтров растет, что приводит к проблемам:

  • Более медленное исполнение
  • Более тяжелая загрузка
  • Более высокий исходный код для поддержки
  • Дополнительные ошибки/сбои
  • Бремя обслуживания

Вопрос

Итак, мы хотели бы сделать эти отдельно устанавливаемые приложения.
Например, шахматный + китайский энтузиаст установил бы 3 приложения:

  • TheApp
  • Плагин TheApp Chess
  • TheApp Chinese plugin

TheApp автоматически обнаружит, какие плагины установлены, и вызовите их по очереди (порядок не имеет значения).

Я думал об использовании намерения THEAPPTRANSFORM, но как получить список приложений с <intent-filter> для THEAPPTRANSFORM и вызвать их по очереди?

Скорость является основным требованием. Я читал, что Намерения в 10+ раз медленнее прямых вызовов... Parcelable помощь здесь?

Если это невозможно, есть ли другое решение?

Ответ 1

Чтобы узнать, какие приложения имеют широковещательный приемник с фильтром THEAPPTRANSFORM, вы можете использовать ниже код

PackageManager pm = getPackageManager();
    Intent intent = new Intent("THEAPPTRANSFORM");
    List<ResolveInfo> info = pm.queryBroadcastReceivers(intent, 0);
    for (ResolveInfo resolveInfo : info) {

        Log.e("apps", "packages = " + resolveInfo.activityInfo.packageName);
    }

Ответ 2

Вам нужен динамически установленный плагин, который не является частью вашего приложения. Я думаю, у вас есть несколько вариантов для этого.

Решение 1: Сценарии

Отправьте интерпретатор языка сценариев с вашим приложением. (например, ruby ​​- http://ruboto.org/). Создайте интерфейс для выполнения этих сценариев. Создайте центральную базу данных таких скриптов или загрузите их из внешнего хранилища. Теперь вы можете выполнить эти сценарии и получить требуемый результат.

Решение 2: AIDL

Использовать удаленную службу в приложениях плагина. Предоставьте AIDL третьим сторонам для разработки приложений с удаленной службой с этим AIDL. Такие службы также должны соответствовать установленному вами фильтру намерений. Теперь вы можете использовать packagemanager для поиска таких сервисов, выбрать один и подключиться к нему. Теперь вы можете вызвать все методы AIDL. Это будет взаимодействие между процессами с использованием связующего, для вашего приложения это будет синхронный вызов. (подробнее см. этот вопрос SO - Доступ к удаленному сервису в другом приложении)

Даунсайд к этому подходу заключается в том, что все эти службы должны запускаться, когда ваше приложение запущено, поэтому вам придется обрабатывать запуск/остановку этих служб. Это также повлияет на потребление энергии, если службы работают в фоновом режиме.

Решение 3: широковещательная/приемная система

Сторонние установленные приложения, у которых есть широковещательный приемник с фильтром намерения для пользовательского намерения, определенного вами. Кроме того, ваше приложение должно иметь широковещательный приемник с особым намерением, который плагины могут вызывать с результатом. Теперь, скажем, вы хотите вызвать сторонний плагин для некоторого преобразования, вы должны это сделать:

Используйте packagemanager, чтобы найти все сторонние приложения, соответствующие ваше намеренное намерение. Отправить трансляцию с extradata о преобразование. Обрабатывать преобразование в широковещательном приемнике приложение плагина. После того, как трансформация будет выполнена, отправьте трансляцию с результат в исходное приложение.

Эта опция полностью асинхронна, и для выполнения без каких-либо гарантий может потребоваться любое количество времени.