Задача Gradle для Sentry не компилируется - PullRequest
4 голосов
/ 18 февраля 2020

Мне нужно добавить инструмент аналитики Sentry в наш Android проект. Чтобы заставить его работать, нужно создать сопоставления для запутанного кода (из Proguard / R8) и загрузить его позже в Sentry.

На сайте https://docs.sentry.io/platforms/android/ это даже описал, как это сделать. Там написано, что нужно создать задачу gradle, похожую на эту:

gradle.projectsEvaluated {
    android.applicationVariants.each { variant ->
        def variantName = variant.name.capitalize();
        def proguardTask = project.tasks.findByName(
            "transformClassesAndResourcesWithProguardFor${variantName}")
        def dexTask = project.tasks.findByName(
            "transformClassesWithDexFor${variantName}")
        def task = project.tasks.create(
                name: "processSentryProguardFor${variantName}",
                type: Exec) {
            workingDir project.rootDir
            commandLine *[
                "sentry-cli",
                "upload-proguard",
                "--write-properties",
                "${project.rootDir.toPath()}/app/build/intermediates/assets" +
                    "/${variant.dirName}/sentry-debug-meta.properties",
                variant.getMappingFile(),
                "--no-upload"
            ]
        }
        dexTask.dependsOn task
        task.dependsOn proguardTask
    }
}

Это должно подождать, пока Proguard не будет завершен, чем скопировать этот файл свойств в ресурсы. Однако, когда я добавляю это в мой Android сценарий gradle, я получаю сообщение об ошибке:

Не удалось создать задачу ': app: processSentryProguardForPlayStoreStagingDebug'.

Нет подписи Метод: java .util.ArrayList.multiply () применим для типов аргументов: (ArrayList) значения: [[sentry-cli, upload-proguard, --write-properties, {Application-Path} / app / build / промежуточные / активы / playStoreStaging / debug / sentry-debug-meta.properties, ...]] Возможные решения: умножение (java .lang.Number), умножение (java .lang.Number)

Я предполагаю, что что-то не так с символом умножения * перед массивом commandLine. Но когда я удаляю его, я получаю ошибку

Не удалось создать задачу ': app: processSentryProguardForPlayStoreStagingDebug'.

Невозможно привести объект 'sentry-cli' с классом 'java .lang.String 'to class' int '

Поэтому я попытался проверить это только с этой строкой

commandLine "sentry-cli", ...

, которая дала мне еще один ошибка

Что пошло не так: Невозможно вызвать метод зависящий от On () для нулевого объекта

Таким образом, я предполагаю, что что-то пошло не так с этим скриптом gradle, так как кажется, что не может быть найдена зависимая задача У кого-нибудь есть идеи, как это исправить (или, если хотите, у вас есть идея, как скопировать этот файл sentry-debug-meta.properties в мои ресурсы другим способом после завершения работы Proguard / R8)?

Спасибо !

-------- РЕДАКТИРОВАТЬ --------

Я заметил кое-что важное. Задачи Gradle определены под другим именем, нежели было определено в руководстве. Глядя на мои задачи, они называются

transformClassesAndResourcesWithR8For...

и

transformClassesWithDexBuilderFor...

Однако я печатаю вариантName затем для проверки, но кажется, что мои задачи не завершены.

В моем списке задач есть

transformClassesAndResourcesWithR8ForPlayStoreStagingDebug

, но не

transformClassesAndResourcesWithR8ForPlayStoreStagingRelease

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

List of my project gradle tasks

------- РЕДАКТИРОВАТЬ 2 --------

Хорошо, я заметил кое-что странное здесь. У некоторых вариантов нет задач. Имеет смысл, что задачи DEBUG не имеют задач R8, но я нашел это здесь:

Вариант: PlayStoreStagingRelease DexTask равен нулю

Вариант: PlayStorePreviewRelease DexTask равен нулю

Вариант: HockeyAppRelease DexTask равен нулю

Вариант: LocalServerRelease DexTask равен нулю

Вариант: PlayStoreProductionRelease DexTask равен нулю

Так как это может быть?

Ответы [ 3 ]

2 голосов
/ 18 февраля 2020

Я бы порекомендовал использовать интеграцию Sentry Gradle (плагин Gradle), которая описана здесь https://docs.sentry.io/platforms/android/#gradle -интеграция

Официальный плагин Android Gradle изменил свои имена задач по сравнению с версиями Версия Gradle также влияет на эти фрагменты кода.

Google также заменил Proguard на R8 и также затронул эти фрагменты кода.

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

Спасибо.

1 голос
/ 18 февраля 2020

java.util.ArrayList.multiply() намекает на это * перед списком [ ], что выглядит странно для меня. Попробуйте удалить *[ ], оставив только List<String> (для начала не ожидается ArrayList):

commandLine "sentry-cli", "upload-proguard", "--write-properties", "${project.rootDir.toPath()}/app/build/intermediates/assets/${variant.dirName}/sentry-debug-meta.properties", variant.getMappingFile(), "--no-upload"

Вам нужно посмотреть, как на самом деле вызываются ваши задачи, но это должно быть что-то похожее:

def r8Task = project.tasks.findByName("transformClassesAndResourcesWithR8For${variantName}")
def d8Task = project.tasks.findByName("transformClassesWithDexBuilderFor${variantName}")

с проверкой null, потому что не в каждом варианте может быть установлено minifyEnabled true:

if(r8Task != null) {
    d8Task.dependsOn task
    task.dependsOn r8Task
}

Может быть, даже предыдущая проверка null требуется, потому что variant.getMappingFile() требуется R8.

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

0 голосов
/ 06 марта 2020

Вот краткое описание шагов, которые я выполнил для интеграции Sentry с моим приложением Android. Эти шаги предназначены для того, чтобы плагин sentry gradle работал должным образом и автоматически загружал файлы сопоставления proguard, не беспокоясь о загрузке с помощью cli. Я предполагаю, что вы бы настроили Sentry SDK, как описано здесь: https://docs.sentry.io/platforms/android/#integrating -the-sdk

  1. Убедитесь, что у вас есть Android Плагин Studio Gradle 3.5.0 (Не 3.6.x , который, кажется, нарушает плагин караульной. Я заметил, что задачи караульной программы или загрузки собственных символов вообще не настроены или не выполнены). Это значение должно быть в root проекте build.gradle в зависимостях блоке

  2. Предоставить sentry.properties файл root папка вашего проекта. Файл sentry.properties должен иметь как минимум следующие значения:

    defaults.project=your_sentry_project_name
    defaults.org=your_sentry_org_name
    auth.token=sentry_project_auth_token

Информацию о создании токенов аутентификации можно получить здесь: https://sentry.io/settings/account/api/auth-tokens/

( Необязательно : если у вас есть сборки) В моем случае у меня есть разные вкусы для моего приложения. Итак, я должен был поместить sentry.properties в мою папку спецификации c в папке / app / src / . Затем я написал задачу Gradle, чтобы скопировать файл спецификации, заданный c sentry.properties , в папку проекта root на этапе настройки gradle. Пример:
    task copySentryPropertiesTask {
        if (getBuildFlavor() != null && !getBuildFlavor().isEmpty()) {
            println("Copying Sentry properties file: ${getBuildFlavor()}")
            copy {
                from "src/${getBuildFlavor()}/"
                include "sentry.properties"
                into "../"
            }
        }
    }

    def getBuildFlavor() {
        Gradle gradle = getGradle()
        String tskReqStr = gradle.getStartParameter().getTaskRequests().toString()
        Pattern pattern;
        if (tskReqStr.contains("assemble"))
            pattern = Pattern.compile("assemble(\\w+)(Release|Debug)")
        else
            pattern = Pattern.compile("generate(\\w+)(Release|Debug)")
        Matcher matcher = pattern.matcher(tskReqStr)
        if (matcher.find())
            return matcher.group(1)
        else {
            println "NO MATCH FOUND"
            return ""
        }
    }

Примечание 1: Вы можете поместить это задание в ваш app / build.gradle где угодно (я поместил его в конце).

Примечание 2: Если Вы выполнили шаг 3 для сборки, вы также можете добавить root в папку sentry.properties в .gitignore . Поскольку он будет копироваться каждый раз при создании сборки.

Теперь Sentry сможет загружать файлы proguard для любых сборок выпуска (или если для любого buildType установлено minifyEnabled = true).

...