如何在发布版本中防止在Android中使用Proguard进行LOG打印

时间:2016-11-04 16:00:03

标签: java android android-logcat

我正在使用Android studio 2.2.2 gradle。 我正在以这种方式在build.gradle中使用Proguard。

 buildTypes {

    release {

        // Enable ProGuard
        minifyEnabled true
        shrinkResources true
        // Common release options
        zipAlignEnabled true
        debuggable false
        jniDebuggable false

        // Notice that the default ProGuard file (SDK-provided) also enables optimization
        // Here we also include a third file which disables the logging (see below)
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'


    }

    debug {
        // We enable ProGuard also for debug builds
        minifyEnabled true

        // Notice that the default ProGuard file (SDK-provided) differs from the release one
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

这是我的节目......

-keepattributes EnclosingMethod

-dontwarn okio.**
-dontwarn retrofit2.Platform$Java8
-dontwarn sun.misc.Unsafe
-dontwarn     org.w3c.dom.bootstrap.DOMImplementatio Registry

-keep class * extends android.

 -assumenosideeffects class    android.util.Log { *; }

 -assumenosideeffects class                  java.io.PrintStream {
public void println(...);
public void print(...);
}

现在,在我的MainActivity.java中,我检查了oncreate中的内容 -

 int i=0;
 Log.d(TAG,"i val:"+i++);
 Toast i value

并始终输出" i val:1"。现在我的问题是为什么要执行日志行?

1 个答案:

答案 0 :(得分:2)

日志行或system.out只是一种在控制台中打印的方法(手机日志文件) 即使这是发布版本,它也会被执行 如果要阻止发布版本中的日志,请执行以下步骤:

创建一个这样的类:

public class LogTag {
  public  static void d(String msg){
    if (ApplicationClass.isDebug){
        Log.d("log_tag", msg);
    }
  }

  public  static void v(String msg){
    if (ApplicationClass.isDebug){
        Log.v("log_tag", msg);
    }
  }
  public  static void e(String msg,Exception e){
    if (ApplicationClass.isDebug){
        Log.e("log_tag", msg, e);
    }
  }
  public  static void e(String msg){
    if (ApplicationClass.isDebug){
        Log.e("log_tag", msg);
    }
  }
}

现在在应用程序类init isDebug变量

public static boolean isDebug = BuildConfig.DEBUG;

然后像这样打印你的日志

LogTag.d('message...');

否则在proguard

中添加这一行
-assumenosideeffects class android.util.Log {
     public static * d(...);
     public static * w(...);
     public static * v(...);
     public static * i(...);
}

让我们深入了解一下如果你反编译apk这就是你将拥有的代码:

    Log.d("TAG", "TAG");
    int i = 0 + 1;
    Log.d("TAG", "i val:" + 0);
    System.out.println("i:" + i);

原始

    Log.d("TAG","TAG");
    int i=0;
    Log.d("TAG","i val:"+i++);
    System.out.println("i:"+i);

因为您可以看到编译器将在我们尝试优化和删除Log.d时发生变化

让我们再举一个例子 反编译代码:

    int index = 0;
    while (index < 10) {
        int i2 = i + 1;
        Log.d("TAG", "i val:" + i);
        index++;
        i = i2;
    }
    System.out.println("i:" + i);

原始代码:

    for(int index = 0;index<10;index++){
        Log.d("TAG","i val:"+i++);
    }
    System.out.println("i:"+i);