1,什么是混淆编译
ProGuard是一个免费的java类文件压缩,优化,混淆器.它探测并删除没有使用的类,字段,方法和属性.它删除没有用的说明并使用字节码得到最大优化.它使用无意义的名字来重命名类,字段和方法.
ProGuard的使用是为了:
1.创建紧凑的代码文档是为了更快的网络传输,快速装载和更小的内存占用.
2.创建的程序和程序库很难使用反向工程.
3.所以它能删除来自源文件中的没有调用的代码
4.充分利用java6的快速加载的优点来提前检测和返回java6中存在的类文件.
 
ProGuard支持那些种类的优化:
除了在压缩操作删除的无用类,字段和方法外,ProGuard也能在字节码级提供性能优化,内部方法有:
1 常量表达式求值
2 删除不必要的字段存取
3 删除不必要的方法调用
4 删除不必要的分支
5 删除不必要的比较和instanceof验证
6 删除未使用的代码
7 删除只写字段
8 删除未使用的方法参数
9 像push/pop简化一样的各种各样的peephole优化
10 在可能的情况下为类添加static和final修饰符
11 在可能的情况下为方法添加private, static和final修饰符
12 在可能的情况下使get/set方法成为内联的
13 当接口只有一个实现类的时候,就取代它
14 选择性的删除日志代码
实际的优化效果是依赖于你的代码和执行代码的虚拟机的。简单的虚拟机比有复杂JIT编译器的高级虚拟机更有效。无论如何,你的字节码会变得更小。
 
需要优化的不被支持技术: 
1 使非final的常量字段成为内联
2 像get/set方法一样使其他方法成为内联
3 将常量表达式移到循环之外
4 Optimizations that require escape analysis 
 
2,启动android中的混淆功能
在需要混淆的工程目录下(package/apps/下的工程)添加proguard.flags文件,该文件即为网络传说中的proguard.cfg,只是命名不一样而已,然后再Android.mk中添加如下两句:
LOCAL_PROGUARD_ENABLED := full
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
上面的full 也可以是custom,如果不写这句,那还得添加如下一句:
TARGET_BUILD_VARIANT := user或者TARGET_BUILD_VARIANT := userdebug
这样后在工程目录下执行mm便可以看到在out目录下生成了形如proguard.classes.jar的东东,这就说明已在编译中启动了proguard
但反编译一看,并未出现网络云说的abcd替代符号,其实代码并未真正混淆:
android在编译时默认关闭了混淆选项,有去研究build/core目录的同志会发现这里也有个proguard.flags文件,其实在proguard的过程中,编译器会调用包括本地目录下和系统定义了的多个proguard.flags文件,而在这个文件中混淆的选项被禁止了,故而编译出来的apk仍未混淆。因此将如下句子注释掉便可实现真正的混淆编译:
# Don't obfuscate. We only need dead code striping.
-dontobfuscate(将该句加个#号注释掉)
 
为什么TARGET_BUILD_VARIANT := user和LOCAL_PROGUARD_ENABLED := full二选一即可,详见build/core/package.mk:
 
LOCAL_PROGUARD_ENABLED:=$(strip $(LOCAL_PROGUARD_ENABLED))
ifndef LOCAL_PROGUARD_ENABLED
ifneq ($(filter user userdebug, $(TARGET_BUILD_VARIANT)),)
# turn on Proguard by default for user & userdebug build
LOCAL_PROGUARD_ENABLED :=full
endif
endif
ifeq ($(LOCAL_PROGUARD_ENABLED),disabled)
# the package explicitly request to disable proguard.
LOCAL_PROGUARD_ENABLED :=
endif
proguard_options_file :=
ifneq ($(LOCAL_PROGUARD_ENABLED),custom)
ifneq ($(all_resources),)
proguard_options_file := $(package_expected_intermediates_COMMON)/proguard_options
endif # all_resources
endif # !custom
LOCAL_PROGUARD_FLAGS := $(addprefix -include ,$(proguard_options_file)) $(LOCAL_PROGUARD_FLAGS)
 
3,混淆代码含义
参数解释:
-include {filename}    从给定的文件中读取配置参数
-basedirectory {directoryname}    指定基础目录为以后相对的档案名称
-injars {class_path}    指定要处理的应用程序jar,war,ear和目录
-outjars {class_path}    指定处理完后要输出的jar,war,ear和目录的名称
-libraryjars {classpath}    指定要处理的应用程序jar,war,ear和目录所需要的程序库文件
-dontskipnonpubliclibraryclasses    指定不去忽略非公共的库类。
-dontskipnonpubliclibraryclassmembers    指定不去忽略包可见的库类的成员。
保留选项
-keep {Modifier} {class_specification}    保护指定的类文件和类的成员
-keepclassmembers {modifier} {class_specification}    保护指定类的成员,如果此类受到保护他们会保护的更好
-keepclasseswithmembers {class_specification}    保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。
-keepnames {class_specification}    保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)
-keepclassmembernames {class_specification}    保护指定的类的成员的名称(如果他们不会压缩步骤中删除)
-keepclasseswithmembernames {class_specification}    保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)
-printseeds {filename}    列出类和类的成员-keep选项的清单,标准输出到给定的文件
压缩
-dontshrink    不压缩输入的类文件
-printusage {filename}
-whyareyoukeeping {class_specification}    
优化
-dontoptimize    不优化输入的类文件
-assumenosideeffects {class_specification}    优化时假设指定的方法,没有任何副作用
-allowaccessmodification    优化时允许访问并修改有修饰符的类和类的成员
混淆
-dontobfuscate    不混淆输入的类文件
-printmapping {filename}
-applymapping {filename}    重用映射增加混淆
-obfuscationdictionary {filename}    使用给定文件中的关键字作为要混淆方法的名称
-overloadaggressively    混淆时应用侵入式重载
-useuniqueclassmembernames    确定统一的混淆类的成员名称来增加混淆
-flattenpackagehierarchy {package_name}    重新包装所有重命名的包并放在给定的单一包中
-repackageclass {package_name}    重新包装所有重命名的类文件中放在给定的单一包中
-dontusemixedcaseclassnames    混淆时不会产生形形色色的类名
-keepattributes {attribute_name,...}    保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.
-renamesourcefileattribute {string}    设置源文件中给定的字符串常量

4,问题集

Proguard returned with error code 1. See console
Warning: com.baidu.mapapi.utils.h: can't find referenced class android.os.storage.StorageManager
Warning: com.baidu.mapapi.utils.h: can't find referenced method 'boolean isExternalStorageRemovable()' in class android.os.Environment
Warning: com.nostra13.universalimageloader.core.decode.ImageDecodingInfo: can't find referenced field 'boolean inPreferQualityOverSpeed' in class android.graphics.BitmapFactory$Options
Warning: com.nostra13.universalimageloader.core.decode.ImageDecodingInfo: can't find referenced field 'android.graphics.Bitmap inBitmap' in class android.graphics.BitmapFactory$Options
Warning: com.nostra13.universalimageloader.core.decode.ImageDecodingInfo: can't find referenced field 'boolean inMutable' in class android.graphics.BitmapFactory$Options
You should check if you need to specify additional program jars.
Warning: there were 1 unresolved references to classes or interfaces.
You may need to specify additional library jars (using '-libraryjars').
Warning: there were 4 unresolved references to program class members.
Your input classes appear to be inconsistent.
You may need to recompile them and try again.
Alternatively, you may have to specify the option
'-dontskipnonpubliclibraryclassmembers'.
java.io.IOException: Please correct the above warnings first.
at proguard.Initializer.execute(Initializer.java:321)
at proguard.ProGuard.initialize(ProGuard.java:211)
at proguard.ProGuard.execute(ProGuard.java:86)
at proguard.ProGuard.main(ProGuard.java:492)

  问题1:

com.baidu.mapapi.utils.h: can't find referenced class android.os.storage.StorageManager

其实找不到引用的这个类是第三方包里面的,而且很多时候我们只需要打乱自己的代码就行了,第三方包的代码就是否要打乱就不要管了。

我们可以使用:

-dontwarn com.xx.bbb.**
-keep class com.xx.bbb.** { *;}

参数来保持第三方库中的类而不乱,-dontwarn和-keep 结合使用,意思是保持com.xx.bbb.**这个包里面的所有类和所有方法而不混淆,接着还叫ProGuard不要警告找不到com.xx.bbb.**这个包里面的类的相关引用。

http://www.vcoo.cc/blog/android-proguard-cant-find-class/

问题2:怎么不混淆注解

-keepattributes *Annotation*
-keep class * extends java.lang.annotation.Annotation { *; }

问题3:Afinal

http://www.tuicool.com/articles/7rmmUr

问题4:混淆后,点击事件被禁

点击事件的代码

@ViewInject(id = R.id.login_check_btn, click = "onCheckLoginShow") Button mLoginBtn;
public void onCheckLoginShow(View view) {

}

原以为是因为点击事件的方法被混淆掉导致代码不能正常运行,

http://stackoverflow.com/questions/7796190/androidonclick-not-working-with-proguard

相关blog

http://blog.csdn.net/lovexjyong/article/details/24652085

http://blog.sina.com.cn/s/blog_5f1ebb8f0101lkqz.html

Android编程之常识 - 混淆的更多相关文章

  1. SHELL脚本编程的常识和VI常用技巧

    来源:http://mprc.pku.edu.cn/mentors/training/TrainingCourses/material/ShellProgramming.HTM#_Toc3751808 ...

  2. Intellij idea 和android studio 代码给混淆

    Intellij idea 和android studio 代码给混淆 一.指令说明-optimizationpasses 5 # 指定代码的压缩级别 -dontusemixedcaseclassna ...

  3. 读《Android编程权威指南》

    因为去年双十二购买了一折的<Android 编程权威指南(第一版)>,在第二版出来后图灵社区给我推送了第二版的优惠码,激动之余就立马下单购买电子书,不得不说Big Nerd Ranch G ...

  4. 菜鸟学Android编程——简单计算器《一》

    菜鸟瞎搞,高手莫进 本人菜鸟一枚,最近在学Android编程,网上看了一些视频教程,于是想着平时手机上的计算器应该很简单,自己何不尝试着做一个呢? 于是就冒冒失失的开撸了. 简单计算器嘛,功能当然很少 ...

  5. 很少有人会告诉你的Android开发基本常识

    原文:很少有人会告诉你的Android开发基本常识. 文章介绍了一些关于开发.测试.版本管理.工具使用等方面的知识.

  6. [电子书] 《Android编程入门很简单》

    <Android编程入门很简单>是一本与众不同的Android学习读物,是一本化繁为简,把抽象问题具体化,把复杂问题简单化的书.本书避免出现云山雾罩.晦涩难懂的讲解,代之以轻松活泼.由浅入 ...

  7. 转:Android 2.3 代码混淆proguard技术介绍

    ProGuard简介 ProGuard是一个SourceForge上非常知名的开源项目.官网网址是:http://proguard.sourceforge.net/. Java的字节码一般是非常容易反 ...

  8. android studio 实现代码混淆

    =======本文章属于转载==========原文章地址:http://my.oschina.net/aibenben/blog/370985 这篇文章等是跟大家分享一在Android studio ...

  9. Eclipse下Android编程代码自动提示

    在用Eclipse进行Android编程,为了代码自动提示,需要进行如下操作: 1.设置 java 文件的代码提示功能 打 开 Eclipse 依次选择 Window > Preferences ...

随机推荐

  1. css样式表中的样式覆盖顺序(转)

    有时候在写CSS的过程中,某些限制总是不起作用,这就涉及了CSS样式覆盖的问题,如下 Css代码   #navigator { height: 100%; width: 200; position:  ...

  2. bisect二分查找模块使用

    import bisectL = [1, 3, 3, 6, 8, 12, 15]x = 5x_insert_point = bisect.bisect_left(L, x)# 在L中查找x,x存在时返 ...

  3. [jquery]判断checkbox是否选中

    if ($("#id").is(":checked"))

  4. React中super(props)和super()以及不写super()的区别

    一.constructor()和super()的基本含义 constructor() -- 构造方法 这是ES6对类的默认方法,通过new命令生成对象实例自动调用的方法.并且,该方法是类中必须要有的, ...

  5. luogu P1107 最大整数

    题目描述 设有n个正整数 (n<=20), 将它们连接成一排, 组成一个最大的多位整数. 例如: n=3时, 3个整数13, 312, 343连接成的最大整数为: 34331213 又如: n= ...

  6. [CF396E]On Iteration of One Well-Known Function

    题意:给定$n=\prod\limits_{i=1}^mp_i^{a_i}$,求$\varphi\left(\cdots\varphi\left(n\right)\cdots\right)$(有$k$ ...

  7. 5.10(java学习笔记)容器的同步控制与只读设置

    1.容器的同步控制 像我们平常使用的容器有些是不同步的即线程不安全,例如HashMap等,在多线程时可能出现并发问题. 而有些容器又是同步的,例如Hashtable. 有些时候我们需要将这些不同步的容 ...

  8. [Markdown]纯文本标记语言MarkdowPad2--MD语法知识

    ##1.标题 代码 注:# 后面保持空格 # h1 ## h2 ### h3 #### h4 ##### h5 ###### h6 ####### h7 // 错误代码 ######## h8 // ...

  9. 数列求和 Exercise06_13

    /** * @author 冰樱梦 * 时间:2018年下半年 * 题目:数列求和 * */ public class Exercise06_13 { public static void main( ...

  10. 泳池迷宫(p24)

    /*2018年8月26日15:55:29作者:冰樱梦page-24泳池迷宫*/public class swiming{public static void main(String[] args){i ...