根据谷歌,我必须在发布我的Android应用程序谷歌播放之前“停用源代码中的Log方法的任何调用”。出版清单第3节节选:

在构建应用程序发布之前,请确保禁用了日志记录并禁用了调试选项。您可以通过删除源文件中对Log方法的调用来禁用日志记录。

我的开源项目很大,每次发布都要手动完成,这很痛苦。此外,删除Log行可能很棘手,例如:

if(condition)
  Log.d(LOG_TAG, "Something");
data.load();
data.show();

如果注释Log行,则该条件将应用于下一行,并且可能不会调用load()。这样的情况是否罕见到我可以决定它不应该存在?

那么,是否有更好的源代码级方法来做到这一点呢?或者是一些聪明的ProGuard语法,有效但安全地删除所有Log行?


当前回答

我知道这是个老问题了,但你为什么不把所有的日志调用都换成 布尔logCallWasHere = true;//——剩下的日志在这里

这就是为什么你会知道什么时候你想把它们放回去,他们不会影响你的if语句调用:)

其他回答

克里斯托弗的Proguard解决方案是最好的,但如果因为任何原因你不喜欢Proguard,这里有一个非常低技术含量的解决方案:

评论日志:

find . -name "*\.java" | xargs grep -l 'Log\.' | xargs sed -i 's/Log\./;\/\/ Log\./g'

取消日志:

find . -name "*\.java" | xargs grep -l 'Log\.' | xargs sed -i 's/;\/\/ Log\./Log\./g'

一个限制是您的日志记录指令不能跨越多行。

(在项目根的UNIX shell中执行这些行。如果使用Windows,请使用UNIX层或使用等效的Windows命令)

我在谷歌IO示例应用程序中使用了LogUtils类。我将其修改为使用特定于应用程序的DEBUG常量而不是BuildConfig。因为BuildConfig. DEBUG。DEBUG不可靠。然后在我的课程中,我有以下内容。

import static my.app.util.LogUtils.makeLogTag;
import static my.app.util.LogUtils.LOGV;

public class MyActivity extends FragmentActivity {
  private static final String TAG = makeLogTag(MyActivity.class);

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

    LOGV(TAG, "my message");
  }
}

Per android.util.Log提供了一种启用/禁用日志的方法:

public static native boolean isLoggable(String tag, int level);

默认情况下,isLoggable(…)方法返回false,只有在你在设备中设置prop后,像这样:

adb shell setprop log.tag.MyAppTag DEBUG

这意味着DEBUG级别以上的任何日志都可以打印出来。参考android文档:

Checks to see whether or not a log for the specified tag is loggable at the specified level. The default level of any tag is set to INFO. This means that any level above and including INFO will be logged. Before you make any calls to a logging method you should check to see if your tag should be logged. You can change the default level by setting a system property: 'setprop log.tag. ' Where level is either VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT, or SUPPRESS. SUPPRESS will turn off all logging for your tag. You can also create a local.prop file that with the following in it: 'log.tag.=' and place that in /data/local.prop.

所以我们可以使用自定义log util:

public final class Dlog 
{
    public static void v(String tag, String msg)
    {
        if (Log.isLoggable(tag, Log.VERBOSE))
            Log.v(tag, msg);
    }

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

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

    public static void w(String tag, String msg)
    {
        if (Log.isLoggable(tag, Log.WARN))
            Log.w(tag, msg);
    }

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

这就是我过去在我的android项目上所做的。

在Android Studio我们可以做类似的操作,Ctrl+Shift+F从整个项目(命令+Shift+F在MacOs)和Ctrl+Shift+R替换((命令+Shift+R在MacOs))

我会考虑使用roboguice的日志记录工具,而不是内置的android.util.Log

它们的功能会自动禁用发布版本的调试和详细日志。 此外,您还可以免费获得一些漂亮的功能(例如,可定制的日志记录行为,每个日志的额外数据等等)

使用proguard可能是相当麻烦的,除非您有一个很好的理由(禁用日志不是一个好理由),否则我不会经历配置和使其与应用程序一起工作的麻烦。