Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/198.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 哨兵的Gradle任务未编译_Android_Gradle_Proguard_Sentry_Android R8 - Fatal编程技术网

Android 哨兵的Gradle任务未编译

Android 哨兵的Gradle任务未编译,android,gradle,proguard,sentry,android-r8,Android,Gradle,Proguard,Sentry,Android R8,我必须将分析工具Sentry添加到我们的Android项目中。为了使其工作,需要为模糊代码(来自Proguard/R8)创建映射,并稍后将其上载到Sentry 网站上甚至描述了如何做到这一点。 有人写道,需要创建一个gradle任务,如下所示: gradle.projectsEvaluated { android.applicationVariants.each { variant -> def variantName = variant.name.capitali

我必须将分析工具Sentry添加到我们的Android项目中。为了使其工作,需要为模糊代码(来自Proguard/R8)创建映射,并稍后将其上载到Sentry

网站上甚至描述了如何做到这一点。 有人写道,需要创建一个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, --写入属性,{Application Path}/app/build/intermediates/assets/playStoreStaging/debug/sentry-debug-meta.properties, …]]可能的解决方案:乘法(java.lang.Number), 乘法(java.lang.Number)

我假设命令行数组之前的乘法符号*有问题。但是当我删除它时,我得到了错误

无法创建任务 “:app:processSentryProguardForPlayStoreStagingDebug”

无法将类为“java.lang.String”的对象“sentry cli”强制转换为类“int”

所以我试着用那条线来测试这个

commandLine "sentry-cli", ...
这又给了我一个错误

错误:无法对null对象调用方法dependsOn()

因此,我假设gradle脚本确实出了问题,因为似乎找不到依赖的任务。有没有人知道如何解决这个问题(或者有没有人知道如何在Proguard/R8完成后以另一种方式将sentry-debug-meta.properties文件复制到我的资产中)

谢谢

------编辑-----

我注意到一些重要的事情。 gradle任务的定义名称与手册中定义的名称不同。看看我的任务,我把它们命名了

transformClassesAndResourcesWithR8For...

但是,我打印了variantName以供检查,但我的任务似乎不完整

在我的任务列表中,存在

transformClassesAndResourcesWithR8ForPlayStoreStagingDebug
但不是

transformClassesAndResourcesWithR8ForPlayStoreStagingRelease
因此无法找到任务。我认为这才是真正的问题所在。那么这些gradle任务是在哪里定义的呢

-------编辑2--------

好吧,我注意到这里有点奇怪。有些变体没有任务。调试任务没有R8任务是有道理的,但我在这里发现:

变量:PlayStoreStagingRelease任务为空

变量:PlayStorePreviewRelease任务为空

变量:hockeyapplease任务为空

变量:LocalServerRelease任务为空

变量:PlayStoreProductionRelease任务为空


这怎么可能呢?

java.util.ArrayList.multiply()
[]
列表前面提示
*
,我觉得很奇怪。尝试删除
*[]
,只保留
列表
(首先,不需要
数组列表
):

您必须查看您的任务实际上是如何被调用的,但它应该是类似的:

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任务可能是因为没有代码(没什么可做的)。

我建议使用这里描述的Sentry-Gradle集成(Gradle插件)

官方的Android Gradle插件更改了其任务名称而不是版本,Gradle版本也会影响这些代码片段

谷歌还用R8取代了Proguard,它也影响了这些代码片段

有没有理由不使用Sentry-Gradle集成?如果是这样,我们将研究更新它们


谢谢。

以下是我将Sentry与Android应用程序集成的步骤摘要。这些步骤是为了确保sentry gradle插件按预期工作,并自动上载proguard映射文件,而无需担心使用cli上载。我假设您已经按照如下所述设置了Sentry SDK:

  • 确保您有Android Studio gradle插件3.5.0(而不是3.6.x,这似乎破坏了sentry插件。我发现sentry proguard或本机符号上传任务根本没有配置或执行)。此值应位于根项目的依赖项中的build.gradle块中

  • 为项目的根文件夹提供一个sentry.properties文件。sentry.properties文件至少应具有以下值:

  • 您可以在此处获取有关生成身份验证令牌的信息:

  • 可选:如果您有构建风格)在我的情况下,我的应用程序有不同的风格。因此,我不得不将sentry.properties放在/app/src/文件夹中我的风味特定文件夹中。然后,我编写了一个gradle任务,在gradle的配置阶段将特定于味道的sentry.properties文件复制到项目的根文件夹中。例如:
  • 注1:您可以将此任务放在app/build.gradle的任何位置(我已将其放在末尾)

    注2:如果按照步骤3进行构建,还可以在.gitignore中添加根文件夹的sentry.properties。因为,每次创建生成时都会复制它


    Sentry现在应该能够为任何发布版本上载proguard文件(或者如果您为任何构建类型设置minifyEnabled=true)。

    如我的问题中所述,在执行此操作时,我收到错误“无法在null对象上调用方法dependsOn()”,因此我猜gradle任务本身不知何故被破坏,
    def r8Task = project.tasks.findByName("transformClassesAndResourcesWithR8For${variantName}")
    def d8Task = project.tasks.findByName("transformClassesWithDexBuilderFor${variantName}")
    
    if(r8Task != null) {
        d8Task.dependsOn task
        task.dependsOn r8Task
    }
    
        defaults.project=your_sentry_project_name
        defaults.org=your_sentry_org_name
        auth.token=sentry_project_auth_token
    
        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 ""
            }
        }