Можете ли вы прочитать/изменить/заменить файл AndroidManifest.xml с помощью пользовательского обработчика аннотаций

Я изучаю пользовательские процессоры аннотаций для приложений Android.

У меня есть вариант использования, когда я хотел бы иметь возможность использовать процессор аннотаций для чтения/изменения AndroidManifest.xml и добавления следующего раздела намерений для всех действий, упомянутых там?

        <intent-filter>
            <action android:name="com.my.package.name.my_activity.open"/>
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>

Это возможно?


person Hector    schedule 19.05.2020    source источник


Ответы (3)


Это очень интересный вопрос, но я не думаю, что вы могли бы решить такую ​​задачу с помощью процессора аннотаций, поскольку они работают на уровне генерации кода Kotlin/Java.

Как бы вы аннотировали XML @Something, чтобы он по-прежнему оставался действительным XML?

Взгляните на это:

KoltinConf18 — обработка аннотаций в Kotlin

Скриншот из записи выступления на youtube

В 7:18 Зак переходит к обработке аннотаций в Java, и в основном он говорит:

  • Происходит во время компиляции
  • И вы не можете изменить код, просто сгенерируйте больше

Таким образом, используя простую обработку аннотаций, вы не можете изменить уже существующий файл AndroidManifest.xml.

Альтернативой может быть написание плагина Gradle, который генерирует эти биты XML и объединяет их с текущим файлом XML, который уже существует в проекте.

Что-то из макушки моей головы может быть:

  1. Создайте аннотацию и отметьте все действия, которые вы хотите ввести в этот фрагмент кода.
  2. На стороне плагина; когда вы пишете задачу Gradle; вы можете использовать отражение и выяснить, какие классы аннотированы таким расширением. Или просто заставьте программиста поместить эти действия в определенный каталог внутри исходной папки, что было бы намного проще
  3. С полными именами классов вы можете просмотреть узлы <activity> в AndroidManifest.xml, отфильтровать имена классов, которые не соответствуют списку аннотированных имен классов.
  4. Измените эти узлы фрагментом кода, который вы хотите внедрить.

Чтобы приступить к написанию подключаемого модуля Gradle, посмотрите здесь

Простым примером для начала может быть:

Шаг 1

Вы создаете отдельный модуль для написания своего плагина, если он становится слишком громоздким, но для этого простого примера я решил поместить его прямо в файл build.gradle.kts. Это не обязательно должен быть файл kotlin Gradle, но я лучше разбираюсь в Kotlin, чем в Groovy :)

шаг 1

Как видите, я создал текст testFile.txt в корне проекта.

В коде я просто перехожу к нему и читаю его; распечатайте его содержимое, а затем измените его.

Вы можете сделать то же самое со своим AndroidManifes.xml. Затем вам нужно будет рекурсивно перебирать исходные файлы из вашего srcDir в поисках всех этих действий, аннотированных вашей специальной аннотацией, и сохранять все полные имена классов внутри файла List<String>. Затем выполните необходимые замены внутри AndroidManifest

Обратите внимание, что с этой базовой конфигурацией задача Gradle появляется на вкладке Gradle внутри категории others, чтобы изменить это, немного выйдя за рамки обработки аннотаций.

Шаг 2, прибыль

шаг 2

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

person Some random IT boy    schedule 22.05.2020
comment
Я не думал об использовании @MyAnnotation в XML, я хотел аннотировать каждый класс Activity, а затем изменить связанный файл AndroidManifest, добавив фрагмент XML, показанный в моем вопросе. - person Hector; 22.05.2020
comment
Вы можете обрабатывать аннотации во время выполнения или во время компиляции. Проблема в том, что когда APK генерирует код, который вы можете сгенерировать для самого действия, этот код на самом деле не может касаться манифеста. Решением может быть плагин Gradle, который запускается перед всем процессом компиляции и выполняет такие изменения в файле AndroidManifest. Как и плагин для привязки данных. Когда вы запускаете синхронизацию с gradle, он проходит через макеты и проверяет те, чей первый узел <layout>, для создания классов привязки. Вы можете сделать то же самое и изменить AndroidManifest в своем проекте. - person Some random IT boy; 22.05.2020
comment
Взгляните, я включил небольшой пример того, как создать простой плагин Gradle, который приближается к тому, что вы хотите сделать. - person Some random IT boy; 22.05.2020
comment
Спасибо за щедрость, я рад, что это было полезно - person Some random IT boy; 30.05.2020

У вас может быть шаблон AndroidManifest_template.xml, затем с помощью задачи gradle пройдите через AndroidManifest_template.xml и сгенерируйте настоящий AndroidManifest.xml, который будет использоваться для создания приложения.

Другими словами, AndroidManest.xml будет временной частью сборки, и вы можете использовать любой препроцессор XML, который захотите, чтобы взять шаблон и превратить его в реальный файл.

person user2199860    schedule 22.05.2020

Если вы хотите добавить эти намерения условно в зависимости от варианта вашего приложения, вы можете использовать ароматы gradle и слияние манифестов для достижения этой цели. build/build-variants" rel="nofollow noreferrer">https://developer.android.com/studio/build/build-variants

Также обратитесь к следующему вопросу, например, об использовании gradle для изменения манифеста.

https://stackoverflow.com/a/22759572/9640177

person mayank1513    schedule 29.05.2020