Subho Subho - 1 month ago 11
Android Question

How to prevent LOG print using Proguard in android in Release build

I am using Android studio 2.2.2 gradle.
I am using Proguard in build.gradle in this way.

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'
}
}


And here is my proguard...

-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(...);
}


Now when in my MainActivity.java i check something in oncreate--

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


And output always "i val:1". Now my question is why the log line is executed ?

Answer

Log line or system.out is just a method to print in console (phone log file) even if this is the release build it will get executed if you want to block the logs in release build follow this steps:

Create a class like this:

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);
    }
  }
}

Now in application class init isDebug variable

public static boolean isDebug = BuildConfig.DEBUG;

then print your logs like this

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

else add this lines in proguard

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

let's look in deeper if you decompile the apk this is the code you will have which is :

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

original

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

so as you can see compilers will change as we are trying to optimize and remove Log.d

let's took another example decompiled code:

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

original code:

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