【问题标题】:Android: How to remove SLF4J debug logging with ProGuardAndroid:如何使用 ProGuard 删除 SLF4J 调试日志记录
【发布时间】:2014-01-26 10:31:23
【问题描述】:

我在我的 Android 应用程序中使用 SLF4J 进行日志记录。在发布版本中,我不希望出现所有调试日志,因此我尝试使用 ProGuard 删除它们。但是日志语句仍然打印到 logcat 控制台,我自己无法弄清楚我做错了什么。这是我第一次使用 ProGuard,非常感谢任何帮助!谢谢!

MainActivity.java

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MainActivity {

    private static final Logger log = LoggerFactory
        .getLogger(MainActivity.class.getSimpleName());

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        log.debug("Starting application.");
    }
}

project-proguard.txt

-assumenosideeffects class org.slf4j.Logger {
    public *** trace(...);
    public *** debug(...);
}

project-proguard.txt(扩展为第一个版本不起作用)

-assumenosideeffects class org.slf4j.Logger {
    public *** trace(...);
    public *** debug(...);
}
-assumenosideeffects interface org.slf4j.Logger {
    public *** trace(...);
    public *** debug(...);
}
-assumenosideeffects class * implements org.slf4j.Logger {
    public *** trace(...);
    public *** debug(...);
}
-assumenosideeffects class * implements org.slf4j.Logger {
    public void trace(java.lang.String);
    public void trace(java.lang.String, java.lang.Object);
    public void trace(java.lang.String, java.lang.Object, java.lang.Object);
    public void trace(java.lang.String, java.lang.Object[]);
    public void trace(java.lang.String, java.lang.Throwable);
    public void trace(org.slf4j.Marker, java.lang.String);
    public void trace(org.slf4j.Marker, java.lang.String, java.lang.Object);
    public void trace(org.slf4j.Marker, java.lang.String, java.lang.Object, java.lang.Object);
    public void trace(org.slf4j.Marker, java.lang.String, java.lang.Object[]);
    public void trace(org.slf4j.Marker, java.lang.String, java.lang.Throwable);
    public void debug(java.lang.String);
    public void debug(java.lang.String, java.lang.Object);
    public void debug(java.lang.String, java.lang.Object, java.lang.Object);
    public void debug(java.lang.String, java.lang.Object[]);
    public void debug(java.lang.String, java.lang.Throwable);
    public void debug(org.slf4j.Marker, java.lang.String);
    public void debug(org.slf4j.Marker, java.lang.String, java.lang.Object);
    public void debug(org.slf4j.Marker, java.lang.String, java.lang.Object, java.lang.Object);
    public void debug(org.slf4j.Marker, java.lang.String, java.lang.Object[]);
    public void debug(org.slf4j.Marker, java.lang.String, java.lang.Throwable);
}

logcat - 调试构建

01-08 11:27:02.105  31142-31142/com.example.android D/MainActivity﹕ Starting application.

logcat - 发布版本(不应该存在!)

01-08 11:30:08.615  26483-26483/? D/MainActivity﹕ Starting application.

【问题讨论】:

  • 长配置中唯一对我有用的是引用接口的部分。

标签: android logging proguard slf4j


【解决方案1】:

我遇到了类似的问题,我用两个步骤解决了。

第一步也是最重要的一步

在您的 gradle 文件中,您必须将 proguard-android-optimize.txt 的用法指定为默认文件。

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'

        // With the file below, it does not work!
        //proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

实际上,在默认的proguard-android.txt 文件中,使用两个标志禁用优化:

-dontoptimize
-dontpreverify

proguard-android-optimize.txt 文件没有添加这些行,所以现在assumenosideeffects 可以工作了。

第二步

在你自己的proguard-rules.pro文件中,你可以添加:

-assumenosideeffects class * implements org.slf4j.Logger {
    public *** trace(...);
    public *** debug(...);
    public *** info(...);
    public *** warn(...);
    public *** error(...);
}

【讨论】:

    【解决方案2】:

    您是否在 -optimizations 中指定字段/删除/只写优化? 如下所示:

    -optimizations field/removal/writeonly

    【讨论】:

      【解决方案3】:

      在这个问题上花了很多时间,对我来说 MLProgrammer-CiM 答案有效。我会推荐这个。

      删除了releaseCompiledebugCompile等一些修改。

      publicReleaseImplementation 'org.slf4j:slf4j-api:1.7.25'
      debugImplementation  'org.slf4j:slf4j-android:1.7.25'
      

      【讨论】:

        【解决方案4】:

        不要proguard,只使用SLF4J的no-op版本作为发布版本。

        releaseCompile 'org.slf4j:slf4j-api:1.7.12'
        debugCompile 'org.slf4j:slf4j-android:1.7.12'
        

        【讨论】:

        • 无操作版本的问题是日志及其字符串内容仍在最终的二进制文件中。没有打印任何内容,但出于安全原因,有时最好完全删除日志行:例如,有人可以尝试从最终二进制文件中提取所有字符串。无论如何,它确实回答了这个问题,因为它只是不打印日志。
        • 如果人们正在反编译 apk,我会更担心什么不是日志:P
        • 用 nop 替换根本不安全.. 删除日志的原因是日志可以深入了解 app/lib 的行为以及许多混淆变量的真正含义.真正彻底去除线条至关重要。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-12
        • 1970-01-01
        • 2023-03-09
        • 2012-10-24
        • 2018-03-28
        • 1970-01-01
        相关资源
        最近更新 更多