如何防止rawproto文件生成或自动删除它们?

2023-11-25

Android gradle 插件生成大量.rawproto文件在build/android-profile目录。它们有什么用?有没有办法阻止这种疯狂或自动删除它们?


我已经被它困扰了很长一段时间,现在我注意到有 GB 的内存占用了我小小的 SSD,我决定找出一种方法来禁用它。对我来说,在占据太多空间之前最烦人的事情是gradlew clean留下一个build文件夹后面。

仅测试过com.android.tools.build:gradle:3.0.1,所以YMMV。

TL;DR

For global应用程序阅读最后一部分,每个项目都使用它rootProject's build.gradle:

com.android.build.gradle.internal.profile.ProfilerInitializer.recordingBuildListener =
        new com.android.build.gradle.internal.profile.RecordingBuildListener(
            com.android.builder.profile.ProcessProfileWriter.get());
// and then `gradlew --stop && gradlew clean` to verify no build folder is left behind

调查

谢谢https://stackoverflow.com/a/43910084/253468链接于@杰夫理查兹提及ProcessProfileWriterFactory.java,我在那里放置了一个断点,并通过运行检查谁在调用它gradlew -Dorg.gradle.debug=true --info(不要与--debug)并附加远程调试器。

我循着踪迹发现ProcessProfileWriter.finishAndMaybeWrite创建文件夹并写入。回溯方法调用我发现ProfilerInitializer.recordingBuildListener控制它是否被调用...并且直接由BasePlugin (apply plugin: 'com.android.*').

因此,为了防止发生任何事情,我选择尝试通过预先初始化该静态字段来禁用防护。值得庆幸的是,Groovy(以及 Gradle)没有给出有关 JVM 可见性修饰符的*,因此无需反思,下面就是神奇的一行:

com.android.build.gradle.internal.profile.ProfilerInitializer.recordingBuildListener =
    new com.android.build.gradle.internal.profile.RecordingBuildListener(
        com.android.builder.profile.ProcessProfileWriter.get());

我知道,这有点冗长,但它有效,而且如果您导入内容,它看起来会更好:

ProfilerInitializer.recordingBuildListener = new RecordingBuildListener(ProcessProfileWriter.get());

运用魔法

在单个项目构建中(一个build.gradle) you must应用这个before

apply plugin: 'com.android.application'

在多项目构建中(大多数模板项目:app文件夹,settings.gradle,还有很多build.gradles) 我建议您将其应用到buildscript block:

buildscript {
    // ...
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'
    }
}
// magic line here

确保它位于任何之前apply plugin:s,而不是在 a 内buildscript block.

在全球范围内应用魔法

显然,如果它在一个项目中困扰我们,那么在所有情况下都会困扰我们,所以以下Gradle 的手册,创建一个文件~/.gradle/init.gradle or %USERPROFILE%\.gradle\init.gradle(提个醒该文件夹可以通过以下命令重新定位GRADLE_USER_HOME)包含以下内容:

// NB: any changes to this script require a new daemon (`gradlew --stop` or `gradlew --no-daemon <tasks>`)
rootProject { rootProject -> // see https://stackoverflow.com/a/48087543/253468
    // listen for lifecycle events on the project's plugins
    rootProject.plugins.whenPluginAdded { plugin ->
        // check if any Android plugin is being applied (not necessarily just 'com.android.application')
        // this plugin is actually exactly for this purpose: to get notified
        if (plugin.class.name == 'com.android.build.gradle.api.AndroidBasePlugin') {
            logger.info 'Turning off `build/android-profile/profile-*.(rawproto|json)` generation.'
            // execute the hack in the context of the buildscript, not in this initscript
            new GroovyShell(plugin.class.classLoader).evaluate("""
                com.android.build.gradle.internal.profile.ProfilerInitializer.recordingBuildListener =
                    new com.android.build.gradle.internal.profile.RecordingBuildListener(
                        com.android.builder.profile.ProcessProfileWriter.get());
            """)
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何防止rawproto文件生成或自动删除它们? 的相关文章

随机推荐