Obfuscate Android files

Updated at:

mPaaS Android client applications are written in Java. Java code can be easily reverse-engineered. To protect the Java source code, use ProGuard to obfuscate Android files.

ProGuard is a tool that compresses, optimizes, and obfuscates Java bytecode files.

  • Compression detects and removes unused classes, fields, methods, and properties.

  • Optimization analyzes and optimizes the bytecode of methods.

  • Obfuscation renames classes, variables, and methods using short, meaningless names.

Using ProGuard makes your code smaller, more efficient, and harder to reverse-engineer or crack.

Prerequisite

You have configured an mPaaS project.

About this task

In an mPaaS project that uses a component-based solution, the compilation output of each bundle is an obfuscated dex file. Therefore, you must configure an obfuscation file for each bundle project. The portal project usually has no code and does not require obfuscation.

Code examples

  • Gradle configuration

    android {
      compileSdkVersion 23
      buildToolsVersion "19.1.0"
    
      defaultConfig {
          applicationId "com.youedata.xionganmaster.launcher"
          minSdkVersion 15
          targetSdkVersion 23
          versionCode 1
          versionName "1.0"
      }
      buildTypes {
          release {
              // Obfuscation switch. Specifies whether to obfuscate.
              minifyEnabled true
              // List of obfuscation files. Configures obfuscation rules.
              proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
          }
      }
      lintOptions {
            checkReleaseBuilds false
            // Or, if you prefer, you can continue to check for errors in release builds,
            // but continue the build even when errors are found:
            abortOnError false
      }
    }
  • Obfuscation file example

    The following is a basic obfuscation example. If you add third-party libraries, you must add other obfuscation rules. You can usually obtain the required configuration files from the official websites of the third-party libraries:

      # Add project specific ProGuard rules here.
      # By default, the flags in this file are appended to flags specified
      # in ${sdk.dir}/tools/proguard/proguard-android.txt
      # You can edit the include path and order by changing the proguardFiles
      # directive in build.gradle.
    
      # For more details, see [Shrink your code and resources](http://developer.android.com/guide/developing/tools/proguard.html).
    
      # Add any project specific keep options here:
    
      # If your project uses WebView with JS, uncomment the following
      # and specify the fully qualified class name to the JavaScript interface
      # class:
      # -keepclassmembers class fqcn.of.javascript.interface.for.webview {
      # public *;
      # }
      -optimizationpasses 5
      -dontusemixedcaseclassnames
      -dontskipnonpubliclibraryclasses
      -dontpreverify
      -verbose
      -ignorewarnings
      -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
    
      -keep public class * extends android.app.Activity
      -keep public class * extends android.app.Application
      -keep public class * extends android.app.Service
      -keep public class * extends android.content.BroadcastReceiver
      -keep public class * extends android.content.ContentProvider
      -keep public class com.android.vending.licensing.ILicensingService
      -keep public class com.alipay.mobile.phonecashier.*
      -keepnames public class *
      -keepattributes SourceFile,LineNumberTable
      -keepattributes *Annotation*
    
      #-keep public class * extends com.alipay.mobile.framework.LauncherApplicationAgent {
      #    *;
      #}
    
      #-keep public class * extends com.alipay.mobile.framework.LauncherActivityAgent {
      #    *;
      #}
    
      -keepclasseswithmembernames class * {
          native <methods>;
      }
    
      -keepclasseswithmembernames class * {
          public <init>(android.content.Context, android.util.AttributeSet);
      }
    
      -keepclasseswithmembernames class * {
          public <init>(android.content.Context, android.util.AttributeSet, int);
      }
    
      -keepclassmembers enum * {
          public static **[] values();
          public static ** valueOf(java.lang.String);
      }
    
      -keep class * extends java.lang.annotation.Annotation { *; }
      -keep interface * extends java.lang.annotation.Annotation { *; }
    
      -keep class * implements android.os.Parcelable {
        public static final android.os.Parcelable$Creator *;
      }
    
      -keep public class * extends android.view.View{
          !private <fields>;
          !private <methods>;
      }
    
      -keep class android.util.**{
           public <fields>;
           public <methods>;
       }
    
      -keep public class  com.squareup.javapoet.**{
          !private <fields>;
            !private <methods>;
      }
      -keep public class   javax.annotation.**{
              !private <fields>;
              !private <methods>;
        }
      -keep public class   javax.inject.**{
           !private <fields>;
           !private <methods>;
       }
      -keep interface **{
        !private <fields>;
        !private <methods>;
      }
      # for dagger
        -keep class * extends dagger.internal.Binding
        -keep class * extends dagger.internal.ModuleAdapter
    
        -keep class **$$ModuleAdapter
        -keep class **$$InjectAdapter
        -keep class **$$StaticInjection
    
        -keep class dagger.** { *; }
    
        -keep class javax.inject.**{ *; }
        -keep class * extends dagger.internal.Binding
        -keep class * extends dagger.internal.ModuleAdapter
        -keep class * extends dagger.internal.StaticInjection
    
      # for butterknife
        -keep class butterknife.* { *; }
        -keep class butterknife.** { *; }
        -dontwarn butterknife.internal.**
        -keep class **$$ViewBinder { *; }
    
        -keepclasseswithmembernames class * {
            @butterknife.* <fields>;
        }
    
        -keepclasseswithmembernames class * {
            @butterknife.* <methods>;
        }
    Note

    If you define the framework classes LauncherApplicationAgent and LauncherActivityAgent in your bundle project, make sure to configure them to prevent obfuscation.

  • Avoid obfuscating common components

    If you register common components in metainfo.xml, the compiler checks for their existence at compile-time. To prevent compilation failure, do not obfuscate these components. For example, if you register the following components:

       <metainfo>
       <service>
           <className>com.mpaas.cq.bundleb.MyServiceImpl</className>
           <interfaceName>com.mpaas.cq.bundleb.api.MyService</interfaceName>
           <isLazy>true</isLazy>
       </service>
    </metainfo>

    Add the following to your obfuscation configuration:

      -keep class com.mpaas.cq.bundleb.MyServiceImpl
      -keep class com.mpaas.cq.bundleb.api.MyService