我们在进行Android App 开发的时候经常会使用 Log 这个类来进行 logcat 日志输出。但是这样的输出日志,如果带入发布包内对外发布出去了,会导致程序运行信息暴露给第三方。
一般情况下,大家在网上会查到一个通过 proguard 这个混淆工具来自动删除对 Log的 api 调用的代码。
proguard_rules.pro
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}
但是最近发现这个方法在目前的工程中不生效了,从而导致发布包依然有这个问题。在网上翻越了包括 ProGuard Usage 的一些线上资料以后,在 StackOverflow 上找到了相关的解释。
From http://proguard.sourceforge.net/index.html#manual/usage.html, it says
–assumenosideffects is “Only applicable when optimizing”.
-${sdk.dir}/tools/proguard/proguard-android.txt says: “Optimization is turned off by default. Dex does not like code run through the ProGuard optimize and preverify steps”.
http://researcharea.blogspot.com/2012/04/assumenosideeffects-not-working-in.html
也就是说assumenosideefcts 这个标识真正生效是在 proguard 工具在 optimizing 阶段。而Android 官方默认把这个过程给禁用了。所以这个方法默认是不生效的。
所以查阅 sdk 中的 proguard-android.txt 中的注释知道了。需要将默认配置文件从 proguard-android.txt 切换为 proguard-android-optimize.txt ,而不是直接将 optimizing 置为可用。
然而
我个人觉得还是不要轻易改变 sdk 默认的设置,所以我的解决方案是在Log 这个类上封装了一个 wrapper ,其中包含一个标识。如果标识为发布版本,则不调用 Log 进行输出。 wrapper 大概是下面这样实现。
public class DebugLog {
private static final boolean ENABLE = BuildType.type == BuildType.RELEASE;
public static int d(String tag, String msg){
return ENABLE ? Log.d(tag, msg) : 0;
}
}