Android gradle插件会在.rawproto
目录中生成大量的build/android-profile
文件。它们是用来干什么的?有没有办法禁用这种疯狂行为或自动将其删除?
最佳答案
我已经被它困扰了很长时间了,现在我发现有几千兆字节的空间占用了我很小的SSD,因此我决定寻找一种禁用它的方法。对我来说,在占用太多空间之前最烦人的事情是gradlew clean
,而后没有build
文件夹。
仅与com.android.tools.build:gradle:3.0.1
一起测试,因此为YMMV。
TL; DR
对于全局应用程序,请阅读最后一节,每个项目都可以在rootProject
的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链接到@JeffRichards并提及
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
)中,您必须在之前应用此apply plugin: 'com.android.application'
在多项目构建中(大多数模板项目:
app
文件夹,settings.gradle
和许多build.gradle
),建议您在buildscript
块周围应用它:buildscript {
// ...
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
}
}
// magic line here
确保它在任何
apply plugin:
之前,而不在buildscript
块之内。在全局范围内应用魔术
显然,如果它在一个项目中困扰我们,那么在所有情况下都将如此,因此在Gradle's manual之后,使用
~/.gradle/init.gradle
或%USERPROFILE%\.gradle\init.gradle
创建文件(请注意this folder can be relocated with 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());
""")
}
}
}
关于android-studio - 如何防止rawproto文件生成或自动删除它们?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43521979/