今天闲,所以想把项目加入混淆,可以减小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