一、反编译代码:

  dex2jar这个工具用于将dex文件转换成jar文件

  下载地址:http://sourceforge.net/projects/dex2jar/files/

  jd-gui 这个工具用于将jar文件转换成java代码

  下载地址:http://jd.benow.ca/

  解压dex2jar压缩包后,我们要用到的是d2j-dex2jar.bat这个文件

  步骤:将apk文件进行解压,可以先将文件重命名成.zip后再解压,

  解压后会发现一个classes.dex文件,该文件存放所有java代码,将其拷贝到dex2jar目录下,cmd下执行命令:

    d2j-dex2jar classes.dex

  结果生成 classes-dex2jar.jar 文件,借助 jd-gui 工具打开jar文件查看java代码

二、反编译资源:

  资源文件在打包的时候将被编译,可以使用 apktool

  下载地址:http://ibotpeaches.github.io/Apktool/install/

  将apktool.bat与apktool.jar放在同一个文件夹下,同时将apk文件拷贝到相同目录下,cmd下执行命令:

apktool d Demo.apk

  [注] 使用apktool出现错误,可能是之前使用过apktool的老版本进行过反编译操作,

     apktool会在<C:\Users\Administrator\apktool\framework>目录下生成名为"1.apk"的缓存文件,将它删除就可以。

三、重新打包:

  对于反编译得到的文件,我们可以重新打包成APK文件(比如,软件汉化)。

  如果把反编译后的Demo文件夹重新打包成APK,cmd下执行命令:

apktool b Demo -o New_Demo.apk

  但是目前这个New_Demo.apk不能安装,因为它还没有进行签名。

四、混淆

  借助SDK集成的Proguard工具,不仅可以混淆代码,还可以压缩APK包。

  只需修改build.gradle中的配置

release{
			minifyEnabled true
			proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
		}

minifyEnabled:用于设置是否启用混淆

proguardFiles:用于选定混淆配置文件,proguard-android.txt文件存放于 <Android SDK>/tools/proguard

  普通类会被混淆,包括类名、方法名以及变量名,混淆还会移除从未被调用的方法;

  直接在 proguard-android.txt

proguard-rules.pro 文件,这个文件就是用于编写适用于当前项目的混淆规则。

  重点了解:
    1) 默认的混淆规则 (proguard-android.txt) 

# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html

-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose

# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).
-dontoptimize
-dontpreverify
# Note that if you want to enable optimization, you cannot just
# include optimization flags in your own project configuration file;
# instead you will need to point to the
# "proguard-android-optimize.txt" file instead of this one from your
# project.properties file.

-keepattributes *Annotation*
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService

# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
    native <methods>;
}

# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-keepclassmembers public class * extends android.view.View {
   void set*(***);
   *** get*();
}

# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

-keepclassmembers class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator CREATOR;
}

-keepclassmembers class **.R$* {
    public static <fields>;
}

# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version.  We know about them, and they are safe.
-dontwarn android.support.**

    注释版:   

-dontusemixedcaseclassnames         #混淆时不使用大小写混合类名
-dontskipnonpubliclibraryclasses	#不跳过library中的非public类
-verbose                            #打印混淆的详细信息
-dontoptimize						#表示不进行优化,建议使用此选项,因为根据proguard-android-optimize.txt中的描述,
									#优化可能会造成一些潜在风险,不能保证在所有版本的Dalvik上都正常运行。 
-dontpreverify						#表示不进行预校验。这个预校验是作用在Java平台上的,
									#Android平台上不需要这项功能,去掉之后还可以加快混淆速度

-keepattributes *Annotation*        #表示对注解中的参数进行保留

#表示不混淆以下声明的两个类(这两个类我们基本也用不上,是接入Google原生的一些服务时使用的)
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService

#示不混淆任何包含native方法的类的类名以及native方法名
-keepclasseswithmembernames class * {
    native <methods>;
}

#表示不混淆任何一个View中的setXxx()和getXxx()方法,
#属性动画需要有相应的setter和getter的方法实现,混淆了就无法工作了
-keepclassmembers public class * extends android.view.View {
   void set*(***);
   *** get*();
}

#表示不混淆Activity中参数是View的方法,因为有这样一种用法,在XML中配置android:onClick=”buttonClick”属性,
#当用户点击该按钮时就会调用Activity中的buttonClick(View view)方法,如果这个方法被混淆的话就找不到了。
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

#表示不混淆枚举中的values()和valueOf()方法
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

#表示不混淆Parcelable实现类中的CREATOR字段,
#CREATOR字段是绝对不能改变的,包括大小写都不能变,不然整个Parcelable工作机制都会失败。
-keepclassmembers class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator CREATOR;
}

#表示不混淆R文件中的所有静态字段,
#R文件是通过字段来记录每个资源的id的,字段名要是被混淆了,id也就找不着了
-keepclassmembers class **.R$* {
    public static <fields>;
}

# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version.  We know about them, and they are safe.
-dontwarn android.support.**

    2) 三组六个keep关键字

关键字 

描述

keep

 保留类和类中的成员,防止它们被混淆或移除

keepnames

 保留类和类中的成员,防止它们被混淆,但当成员没有被引用时会被移除

 keepclassmembers

 只保留类中的成员,防止它们被混淆或移除

 keepclassmembernames

 只保留类中的成员,防止它们被混淆,但当成员没有被引用时会被移除

 keepclasseswithmembers

 保留类和类中的成员,防止它们被混淆或移除,前提是指名的类中的成员必须存在

 keepclasseswithmembernames 

 保留类和类中的成员,防止它们被混淆,但当成员没有被引用时会被移除,前提是指名的类中的成员必须存在

    3) 通配符

通配符

描述

<field>

匹配类中的所有字段

<method>

匹配类中的所有方法

<init>

匹配类中的所有构造函数

*

匹配任意长度字符,但不包含分隔符(.)。比如 完整类名com.iisi.test.MyActivity,使用com.*或者com.iisi.*都是无法匹配;

如果只有一个*,那就表示匹配所有的字符

**

匹配任意长度字符,并且包含分隔符(.)。比如 android.support.** 就可以匹配android.support包下所有内容

***

匹配任意参数类型。比如 void set*(***)、*** get*()

...

匹配任意长度的任意类型参数。比如 void test(...) 就可以匹配 void test(String a)或者 void test(int a, String b)