android studio 代码混淆

本文介绍如何在Android项目中实现代码混淆,包括配置步骤、解决常见问题的方法及具体混淆规则示例。

今天闲,所以想把项目加入混淆,可以减小apk体积,也可以优化项目。

本来以前也加入过,但是因为总是报错所以不了了之。

androidstudio 混淆

首先需要在项目的build.gradle文件中加入如下代码。

\

androidstudio都有一个默认混淆的文件,没有也可以自己建一个。

\

 

保证有文件,文件名一样就好了,名字其实可以修改。

 

其实开始也啥都不知道,就再网上慢慢搜,一遍一遍的试。

 

在这里说明几个语法

前面加“#”代表注释,混淆语句前面都有“-

保持某个类不混淆 -keep class com.uyac.test.MainActivity

保持某个包下面的类不混淆 -keep class com.uyac.test **

保持某个包下面的类还有类中代码不混淆 -keep class com.uyac.test**{ *; }

保持继承activity的类 -keep class * extends android.app.Activity (同理Fragment、Service、BroadCast都可以以此混淆)

例如-keep public class * extends android.support.v4.app.Fragment

保持资源类

-keepclassmembers class **.R$* {

?
1
2
<strong>    public static <fields>;
</fields></strong>}

 

 

....

 

这样之后,就要去混淆文件中去加混淆代码了。(混淆代码在文章末尾贴出),我直接说遇到的问题。

 

打包时遇到了这样的错误

Error:Execution failed for task ':ElegantLife2.1.0:transformClassesAndResourcesWithProguardForRelease'.
> java.io.IOException: Can't read [D:\project_as_1\ElegantLife3.0.0_as2\MyUyac\ElegantLife2.1.0\libs\umeng-analytics-v5.2.4.jar] (No such file or directory)

 

这是因为我混淆文件里面有混淆-libraryjarslibs/umeng-analytics-v5.2.4.jar

因为libs下没有这个文件!我的umeng-analytics 版本是v5.6.4 所以编译没通过。

改成-libraryjarslibs/umeng-analytics-v5.6.4.jar 就没问题了

 

 

然后我再次打包,打包是可以成功的,只是打开app在欢迎页就崩了。

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.uyac.elegantlife.tt, PID: 14659
java.lang.NullPointerException: Attempt to invoke virtual method 'int com.uyac.elegantlife.c.bm$a.e()' on a null object reference
at com.uyac.elegantlife.a.z.getView(SourceFile:176)
at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:220)0
at android.widget.AbsListView.obtainView(AbsListView.java:2347)
at android.widget.ListView.makeAndAddView(ListView.java:1864)
at android.widget.ListView.fillDown(ListView.java:698)
at android.widget.ListView.fillFromTop(ListView.java:759)
at android.widget.ListView.layoutChildren(ListView.java:1659)
at android.widget.AbsListView.onLayout(AbsListView.java:2151)
at android.view.View.layout(View.java:15714)
at android.view.ViewGroup.layout(ViewGroup.java:5046)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15714)
at android.view.ViewGroup.layout(ViewGroup.java:5046)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15714)
at android.view.ViewGroup.layout(ViewGroup.java:5046)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1077)
at android.view.View.layout(View.java:15714)
at android.view.ViewGroup.layout(ViewGroup.java:5046)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15714)
at android.view.ViewGroup.layout(ViewGroup.java:5046)
at android.support.v4.view.ViewPager.onLayout(SourceFile:1767)
at android.view.View.layout(View.java:15714)
at android.view.ViewGroup.layout(ViewGroup.java:5046)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15714)
at android.view.ViewGroup.layout(ViewGroup.java:5046)
at android.support.v4.view.ViewPager.onLayout(SourceFile:1767)
at android.view.View.layout(View.java:15714)
at android.view.ViewGroup.layout(ViewGroup.java:5046)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1077)
at android.view.View.layout(View.java:15714)
at android.view.ViewGroup.layout(ViewGroup.java:5046)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15714)
at android.view.ViewGroup.layout(ViewGroup.java:5046)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15714)
at android.view.ViewGroup.layout(ViewGroup.java:5046)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15714)
at android.view.ViewGroup.layout(ViewGroup.java:5046)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15714)
at android.view.ViewGroup.layout(ViewGroup.java:5046)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:15714)
at android.view.ViewGroup.layout(ViewGroup.java:5046)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2091)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.

 

报错如上,(即使打包之后,只要代码中有输出log,也是可以看到的,错误信息也有,可以用于打包后调试,有更好的方法欢迎讨论)

 

这种问题就不好解决了,看样子是一个类部类,而正好欢迎界面过后要启动的界面适配器里面有类部类,所以我就keep了我的适配器包。然后不报错了。

 

但是还没有结束

第三方登录,和分享功能不能用!!!因为用的友盟分享和第三方登录。

 

?
1
<em>#友盟混淆</em>
?
1
<em>-keep class com.umeng.**</em>
?
1
<em>-keep class com.umeng.**{*;}</em>
?
1
2
<em>
</em>
?
1
<em>这样看来,混淆其实也很简单,最主要是找到问题,解决问题。</em>

 

 

最后献上混淆源码

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#指定代码的压缩级别
  -optimizationpasses 5
  #包明不混合大小写
  -dontusemixedcaseclassnames
  #不去忽略非公共的库类
  -dontskipnonpubliclibraryclasses
   #优化  不优化输入的类文件
  -dontoptimize
   #不做预校验
  -dontpreverify
   #混淆时是否记录日志
  -verbose
   # 混淆时所采用的算法
  -optimizations !code/simplification/arithmetic,!field/*,! class /merging/*
   #忽略警告
  -ignorewarning
 
 
   #apk 包内所有 class 的内部结构
   -dump class_files.txt
   #未混淆的类和成员
   -printseeds seeds.txt
   #列出从 apk 中删除的代码
   -printusage unused.txt
   #混淆前后的映射
   -printmapping mapping.txt
 
 
  # 保持哪些类不被混淆 google默认 不混淆 Activity 、Service ... 类的子类
  #混淆了可能编译不通过
  -keep public class * extends android.app.Fragment
  -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 * extends android.app.backup.BackupAgentHelper
  -keep public class * extends android.preference.Preference
  -keep public class com.android.vending.licensing.ILicensingService
 
  #申明第三方库,以免出现调用错误
  -libraryjars libs/alipaySDK- 20150602 .jar
  -libraryjars libs/aliyun-oss-sdk-android- 2.2 . 0 .jar
  -libraryjars libs/AMap_2DMap_V2. 8 .1_20160202.jar
  -libraryjars libs/AMap_Location_V2. 4 .1_20160414.jar
  -libraryjars libs/android-async-http- 1.4 . 8 .jar
  -libraryjars libs/com.umeng.message.lib_v2. 5.0 .jar
  -libraryjars libs/commons-codec- 1.7 .jar
  -libraryjars libs/eventbus- 2.1 . 0 .jar
  -libraryjars libs/gson- 2.6 . 2 .jar
  -libraryjars libs/libammsdk.jar
  -libraryjars libs/okhttp- 3.2 . 0 .jar
  -libraryjars libs/okio- 1.6 . 0 .jar
  -libraryjars libs/SimplifySpan.jar
  -libraryjars libs/umeng-analytics-v5. 6.4 .jar
  -libraryjars libs/universal-image-loader- 1.9 . 5 .jar
  -libraryjars libs/UPPayAssistEx.jar
  -libraryjars libs/UPPayPluginExStd.jar
 
 
   #保护注解
   -keepattributes *Annotation*
 
  #如果有引用v4包可以添加下面这行
  -keep public class * extends android.support.v4.app.Fragment
 
  #如果引用了v4或者v7包
  -dontwarn android.support.**
  -keep public class * extends android.view.View {
      public <init>(android.content.Context);
      public <init>(android.content.Context, android.util.AttributeSet);
      public <init>(android.content.Context, android.util.AttributeSet, int );
      public void set*(...);
  }
 
  #保持 native 方法不被混淆
-keepclasseswithmembernames class * {
    native <methods>;
}
 
  # Keep names - Native method names. Keep all native class /method names.
  -keepclasseswithmembers,allowshrinking class * {
      native <methods>;
  }
 
  #保持自定义控件类不被混淆
  -keepclasseswithmembers class * {
      public <init>(android.content.Context, android.util.AttributeSet);
  }
 
  #保持自定义控件类不被混淆
  -keepclassmembers class * extends android.app.Activity {
     public void *(android.view.View);
  }
 
  #保持 Parcelable 不被混淆
  -keep class * implements android.os.Parcelable {
    public static final android.os.Parcelable$Creator *;
  }
 
  #保持 Serializable 不被混淆
  -keepnames class * implements java.io.Serializable
 
  #保持 Serializable 不被混淆并且 enum 类也不被混淆
  -keepclassmembers class * implements java.io.Serializable {
      static final long serialVersionUID;
      private static final java.io.ObjectStreamField[] serialPersistentFields;
      ! static ! transient <fields>;
      ! private <fields>;
      ! private <methods>;
      private void writeObject(java.io.ObjectOutputStream);
      private void readObject(java.io.ObjectInputStream);
      java.lang.Object writeReplace();
      java.lang.Object readResolve();
  }
 
  #保持枚举 enum 类不被混淆 如果混淆报错,建议直接使用上面的 -keepclassmembers class * implements java.io.Serializable即可
  -keepclassmembers enum * {
      public static **[] values();
      public static ** valueOf(java.lang.String);
  }
 
  #不混淆资源类
  -keepclassmembers class **.R$* {
      public static <fields>;
  }
 
   #不混淆H5交互
-keepattributes *JavascriptInterface*
  #ClassName是类名,H5_Object是与javascript相交互的object,建议以内部类形式书写
-keepclassmembers   class **.ClassName$H5_Object{
                  *;
   }
 
#如果使用有Gson,则添加以下配置
  -keepattributes Signature
  -keepattributes *Annotation*
  -keep class sun.misc.Unsafe { *; }
 
#keep model
-keep class com.uyac.elegantlife.entity.**{*;}
 
#keep 适配器
-keep class com.uyac.elegantlife.adapter.**{*;}
 
#高德定位混淆
-keep class com.amap.api.location.**{*;}
 
-keep class com.amap.api.fence.**{*;}
 
-keep class com.autonavi.aps.amapapi.model.**{*;}
 
#高德2D地图混淆
-keep class com.amap.api.maps2d.**{*;}
 
-keep class com.amap.api.mapcore2d.**{*;}
 
#友盟混淆
-dontwarn com.umeng.**
-keep class com.umeng*.** {*; }
 
 
  #三星应用市场需要添加:sdk-v1. 0.0 .jar,look-v1. 0.1 .jar
  #-libraryjars libs/sdk-v1. 0.0 .jar
  #-libraryjars libs/look-v1. 0.1 .jar
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值