在发布的 Android 应用程序中完全禁用 LogCat 输出?

Posted

技术标签:

【中文标题】在发布的 Android 应用程序中完全禁用 LogCat 输出?【英文标题】:Disable LogCat Output COMPLETELY in release Android app? 【发布时间】:2011-07-30 00:24:12 【问题描述】:

在将应用发布到市场之前关闭我自己的应用的 LogCat 输出非常简单。我也知道如何通过标签和/或 id 有选择地过滤 LogCat 消息以方便我自己的调试。

但现在我对可能更困难的事情感兴趣(也许不可能?):禁用所有 LogCat 输出,尤其是那些来自 TtsService、GoogleLoginService 等第三方服务的输出。

这可能吗?

进一步澄清:我有兴趣为自己过滤掉消息。我对从 android Market 下载我的应用程序的人禁用 3rd-party 消息很感兴趣。这可能吗?

【问题讨论】:

所以你想阻止用户设备上的任何应用写入LogCat输出? 您是指您的应用中包含(或使用)的那些第三方库的日志消息吗? @eldarerathis 不,我想防止任何直接或间接被我的应用使用的应用写入 LogCat 输出。抱歉不够清楚。 @Rajath DSouza 是的,这正是我的意思。我不在乎其他应用程序在独立工作或被其他应用程序使用时显示什么。我只关心他们输出内容以响应我的应用程序的请求/调用。 好吧,这更有意义... 【参考方案1】:

您可以使用ProGuard 完全删除任何未使用返回值的行,方法是告诉 ProGuard 假设不会有问题。

以下 proguard.cfg 块指示删除 Log.d、Log.v 和 Log.i 调用。

-assumenosideeffects class android.util.Log 
    public static *** d(...);
    public static *** w(...);
    public static *** v(...);
    public static *** i(...);

最终结果是这些日志行不在您的发行版 apk 中,因此任何使用 logcat 的用户都不会看到 d/v/i 日志。

【讨论】:

这个技巧令人难以置信。它已经值得+1了。在确保它确实在我的应用程序中产生所需的结果后,我将接受答案。谢谢! ProGuard 真的很强大!您还可以使用此技巧来删除其他形式的开发代码,而不仅仅是日志记录。 启用开发人员功能的代码,例如附加菜单选项。日志记录是我能想到的唯一应该删除的常见内容。 您需要注意这一点,因为您添加了类似 Log.d(someStrVar + "sensitive info here"); 之类的评论。敏感信息字符串仍会进入 APK 中的 classes.dex 文件。因为隐式使用 stringbuilder 时 Proguard 存在优化问题 这应该被添加到答案中!正如@phnmnn 所说 - 以下行应设置为grade.build 文件: proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'【参考方案2】:

如果你不使用proguard,你必须自己管理日志并且在manifest文件中make dubuggable false

<application
    android:name="MyApplication"
    android:icon="@drawable/gift"
    android:label="@string/app_name" android:debuggable="@bool/build_log">

这是我的自定义日志类

public class Lol 

    public static final boolean ENABLE_LOG = true & MyApplication.sDebug;

    private static final boolean DEBUG = true & ENABLE_LOG;

    private static final boolean VERBOSE = true & ENABLE_LOG;

    private static final boolean TEMP = true & ENABLE_LOG;

    private static final boolean WARNING = true & ENABLE_LOG;

    private static final boolean INFO = true & ENABLE_LOG;

    private static final boolean ERROR = true & ENABLE_LOG;

    public static void obvious(String tag, String msg) 
        if (DEBUG) 
            msg = "*********************************\n" + msg
                    + "\n*********************************";
            Log.d(tag, msg);
        
    

    public static void d(String tag, String msg) 
        if (DEBUG)
            Log.d(tag, msg);
    

    public static void d(boolean bool, String tag, String msg) 
        if (TEMP&bool)
            Log.d(tag, msg);
    

    public static void i(String tag, String msg) 
        if (INFO)
            Log.i(tag, msg);
    

    public static void e(String tag, String msg) 
        if (ERROR)
            Log.e(tag, msg);
    

    public static void e(boolean bool, String tag, String msg) 
        if (TEMP&bool)
            Log.e(tag, msg);
    

    public static void v(String tag, String msg) 
        if (VERBOSE)
            Log.v(tag, msg);
    

    public static void w(String tag, String msg) 
        if (WARNING)
            Log.w(tag, msg);
    

    public static String getStackTraceString(Exception e) 
        return Log.getStackTraceString(e);
    

    public static void w(String tag, String msg, Exception e) 
        if (WARNING)
            Log.w(tag, msg,e);
    

【讨论】:

因为SDK Tools 8 没有必要手动设置 android:debuggable 标志。这消除了发布可调试版本的风险。 只是好奇(我刚刚偶然发现了这个问题),你有什么理由使用true &amp; ENABLE_LOG 而不是只使用ENABLE_LOG?我没有看到任何不同的功能...... 你还在尝试调用函数和发送参数,不要认为这是个好主意,最好使用if (BuildConfig.DEBUG) Log.i(TAG, msg);【参考方案3】:

David Caunt 提供的出色答案似乎不适用于proguard-android-optimize.txt 中定义的规则。

当前版本的 ProGuard 似乎期望返回参数的类型限定符,而不是使用通配符 ***

-assumenosideeffects class android.util.Log 
    public static int   d(...);
    public static int   w(...);
    public static int   v(...);
    public static int   i(...);
    public static int wtf(...);

【讨论】:

【参考方案4】:

在app build.gradle 文件集中:

release 
    minifyEnabled true
     ……

在 proguard-rules.pro 中:

-assumenosideeffects class android.util.Log 
  public static *** v(...);
  public static *** d(...);
  public static *** i(...);
  public static *** w(...);
  public static *** e(...);

-ignorewarnings

它对我有用。

【讨论】:

【参考方案5】:

您可以将 debuggable false 放在 buildTypes 版本上。

buildTypes 

     release 
        debuggable false
        ...
     


【讨论】:

【参考方案6】:

接下来我通常会做:

if (BuildConfig.DEBUG) Log.i(TAG, msg);

如果您有很多依赖项(库)并且它们写得不好,那么可以使用https://***.com/a/5553290/4548520

让行更短:

private final static boolean DEBUG = BuildConfig.DEBUG;

if (DEBUG) Log.i(TAG, msg_1);

if (DEBUG) Log.e(TAG, msg_error_2);

【讨论】:

【参考方案7】:

除了将 Android SDK 中的默认 ProGuard 设置(“proguard-android.txt”文件)换成“proguard-android-optimize.txt”优化文件。该文件也可在此 Android SDK 文件夹中找到,具有相同的规则,但启用了优化。

【讨论】:

【参考方案8】:

看起来你也可以简单地使用&lt;methods&gt;速记,而不是枚举所有类的方法:

-assumenosideeffects class a.b.c.DebugLogs 
    <methods>;

使用com.android.tools.build:gradle 版本为4.0.0 为我工作。

【讨论】:

以上是关于在发布的 Android 应用程序中完全禁用 LogCat 输出?的主要内容,如果未能解决你的问题,请参考以下文章

Android:如何在 Edittext 中完全禁用复制和粘贴功能

如何在init.rc文件中完全禁用Android L中的SELinux?

如何在 Rails 3.1 应用程序中完全禁用 CoffeeScript?

处理请求时禁用按钮

如何禁用android地图标记单击自动中心

使用 Visual Studio 2015 在 Xamarin 中禁用发布 Android 应用程序选项