Android之如何混淆代码和相关配置

昨天,客户想看一下目前项目开发到什么程度了,于是需要将项目签名打包成apk,结果打包的时候出错了,吃惊,什么情况。等成功打包以后,安装起来发现部分功能又报错了,囧,所幸最后还是解决了。在这里记录一下遇到的错误和解决方法。

1.如何混淆

将代码混淆起来,这样可以防止在apk被人反编译后而被别人直接看到源码,混淆方法很简单,当我们创建好项目时,已经自动为我们生成了混淆文件,老版的ADT生成的是proguard.cfg文件,而新版的ADT则是以proguard-project.txt替代了它。两则配置方法一致,只要在project.properties文件中引入就好。前者是将project.properties的“#  proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt”的“#”去掉就可以了,后者加入一句proguard.config=proguard.cfg即可。

 

2.如何防止第三方jar包混淆

我使用的混淆文件是proguard.cfg。

开头提到的第一个打包失败的原因是因为引入了第三方jar包。

所报错误如下

  1  Proguard returned with error code 1. See console
  2  Note: there were 1465 duplicate class definitions.
  3  Warning: library class android.net.http.AndroidHttpClient extends or implements program class org.apache.http.client.HttpClient
  4  Warning: org.apache.http.client.protocol.RequestAddCookies: can‘t find referenced class org.apache.commons.logging.LogFactory
  5  Warning: org.apache.http.client.protocol.RequestAddCookies: can‘t find referenced class org.apache.commons.logging.LogFactory
  6  Warning: org.apache.http.client.protocol.RequestAuthCache: can‘t find referenced class org.apache.commons.logging.LogFactory
  7  Warning: org.apache.http.client.protocol.RequestAuthCache: can‘t find referenced class org.apache.commons.logging.LogFactory
  8  Warning: org.apache.http.client.protocol.RequestAuthenticationBase: can‘t find referenced class org.apache.commons.logging.LogFactory
  9  Warning: org.apache.http.client.protocol.RequestAuthenticationBase: can‘t find referenced class org.apache.commons.logging.LogFactory
 10  Warning: org.apache.http.client.protocol.RequestClientConnControl: can‘t find referenced class org.apache.commons.logging.LogFactory
 11  Warning: org.apache.http.client.protocol.RequestClientConnControl: can‘t find referenced class org.apache.commons.logging.LogFactory
 12  Warning: org.apache.http.client.protocol.ResponseAuthCache: can‘t find referenced class org.apache.commons.logging.LogFactory
 13  Warning: org.apache.http.client.protocol.ResponseAuthCache: can‘t find referenced class org.apache.commons.logging.LogFactory
 14  Warning: org.apache.http.client.protocol.ResponseProcessCookies: can‘t find referenced class org.apache.commons.logging.LogFactory
 15  Warning: org.apache.http.client.protocol.ResponseProcessCookies: can‘t find referenced class org.apache.commons.logging.LogFactory
 16  Warning: org.apache.http.impl.auth.BasicScheme: can‘t find referenced class org.apache.commons.codec.binary.Base64
 17  Warning: org.apache.http.impl.auth.BasicScheme: can‘t find referenced class org.apache.commons.codec.binary.Base64
 18  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.apache.commons.logging.LogFactory
 19  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.apache.commons.codec.binary.Base64
 20  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.apache.commons.codec.binary.Base64
 21  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSManager
 22  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSName
 23  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSManager
 24  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSName
 25  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSManager
 26  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSContext
 27  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSContext
 28  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSContext
 29  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSException
 30  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSException
 31  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSException
 32  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.apache.commons.codec.binary.Base64
 33  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.apache.commons.codec.binary.Base64
 34  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.apache.commons.logging.LogFactory
 35  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSManager
 36  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSName
 37  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSContext
 38  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.apache.commons.codec.binary.Base64
 39  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSManager
 40  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.Oid
 41  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.Oid
 42  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSManager
 43  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSName
 44  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSContext
 45  Warning: org.apache.http.impl.auth.GGSSchemeBase: can‘t find referenced class org.ietf.jgss.GSSException
 46  Warning: org.apache.http.impl.auth.KerberosScheme: can‘t find referenced class org.ietf.jgss.Oid
 47  Warning: org.apache.http.impl.auth.KerberosScheme: can‘t find referenced class org.ietf.jgss.Oid
 48  Warning: org.apache.http.impl.auth.KerberosScheme: can‘t find referenced class org.ietf.jgss.GSSException
 49  Warning: org.apache.http.impl.auth.NTLMEngineImpl$NTLMMessage: can‘t find referenced class org.apache.commons.codec.binary.Base64
 50  Warning: org.apache.http.impl.auth.NTLMEngineImpl$NTLMMessage: can‘t find referenced class org.apache.commons.codec.binary.Base64
 51  Warning: org.apache.http.impl.auth.NTLMEngineImpl$NTLMMessage: can‘t find referenced class org.apache.commons.codec.binary.Base64
 52  Warning: org.apache.http.impl.auth.NegotiateScheme: can‘t find referenced class org.apache.commons.logging.LogFactory
 53  Warning: org.apache.http.impl.auth.NegotiateScheme: can‘t find referenced class org.ietf.jgss.Oid
 54  Warning: org.apache.http.impl.auth.NegotiateScheme: can‘t find referenced class org.ietf.jgss.Oid
 55  Warning: org.apache.http.impl.auth.NegotiateScheme: can‘t find referenced class org.ietf.jgss.GSSException
 56  Warning: org.apache.http.impl.auth.NegotiateScheme: can‘t find referenced class org.ietf.jgss.GSSException
 57  Warning: org.apache.http.impl.auth.NegotiateScheme: can‘t find referenced class org.apache.commons.logging.LogFactory
 58  Warning: org.apache.http.impl.auth.NegotiateScheme: can‘t find referenced class org.ietf.jgss.GSSException
 59  Warning: org.apache.http.impl.auth.NegotiateScheme: can‘t find referenced class org.ietf.jgss.Oid
 60  Warning: org.apache.http.impl.auth.SPNegoScheme: can‘t find referenced class org.ietf.jgss.Oid
 61  Warning: org.apache.http.impl.auth.SPNegoScheme: can‘t find referenced class org.ietf.jgss.Oid
 62  Warning: org.apache.http.impl.auth.SPNegoScheme: can‘t find referenced class org.ietf.jgss.GSSException
 63  Warning: org.apache.http.impl.client.AbstractAuthenticationHandler: can‘t find referenced class org.apache.commons.logging.LogFactory
 64  Warning: org.apache.http.impl.client.AbstractAuthenticationHandler: can‘t find referenced class org.apache.commons.logging.LogFactory
 65  Warning: org.apache.http.impl.client.AbstractHttpClient: can‘t find referenced class org.apache.commons.logging.LogFactory
 66  Warning: org.apache.http.impl.client.AbstractHttpClient: can‘t find referenced class org.apache.commons.logging.LogFactory
 67  Warning: org.apache.http.impl.client.AuthenticationStrategyAdaptor: can‘t find referenced class org.apache.commons.logging.LogFactory
 68  Warning: org.apache.http.impl.client.AuthenticationStrategyAdaptor: can‘t find referenced class org.apache.commons.logging.LogFactory
 69  Warning: org.apache.http.impl.client.AuthenticationStrategyImpl: can‘t find referenced class org.apache.commons.logging.LogFactory
 70  Warning: org.apache.http.impl.client.AuthenticationStrategyImpl: can‘t find referenced class org.apache.commons.logging.LogFactory
 71  Warning: org.apache.http.impl.client.AutoRetryHttpClient: can‘t find referenced class org.apache.commons.logging.LogFactory
 72  Warning: org.apache.http.impl.client.AutoRetryHttpClient: can‘t find referenced class org.apache.commons.logging.LogFactory
 73  Warning: org.apache.http.impl.client.DefaultRedirectHandler: can‘t find referenced class org.apache.commons.logging.LogFactory
 74  Warning: org.apache.http.impl.client.DefaultRedirectHandler: can‘t find referenced class org.apache.commons.logging.LogFactory
 75  Warning: org.apache.http.impl.client.DefaultRedirectStrategy: can‘t find referenced class org.apache.commons.logging.LogFactory
 76  Warning: org.apache.http.impl.client.DefaultRedirectStrategy: can‘t find referenced class org.apache.commons.logging.LogFactory
 77  Warning: org.apache.http.impl.client.DefaultRequestDirector: can‘t find referenced class org.apache.commons.logging.LogFactory
 78  Warning: org.apache.http.impl.client.DefaultRequestDirector: can‘t find referenced class org.apache.commons.logging.LogFactory
 79  Warning: org.apache.http.impl.client.HttpAuthenticator: can‘t find referenced class org.apache.commons.logging.LogFactory
 80  Warning: org.apache.http.impl.client.HttpAuthenticator: can‘t find referenced class org.apache.commons.logging.LogFactory
 81  Warning: org.apache.http.impl.conn.BasicClientConnectionManager: can‘t find referenced class org.apache.commons.logging.LogFactory
 82  Warning: org.apache.http.impl.conn.BasicClientConnectionManager: can‘t find referenced class org.apache.commons.logging.LogFactory
 83  Warning: org.apache.http.impl.conn.DefaultClientConnection: can‘t find referenced class org.apache.commons.logging.LogFactory
 84  Warning: org.apache.http.impl.conn.DefaultClientConnection: can‘t find referenced class org.apache.commons.logging.LogFactory
 85  Warning: org.apache.http.impl.conn.DefaultClientConnection: can‘t find referenced class org.apache.commons.logging.LogFactory
 86  Warning: org.apache.http.impl.conn.DefaultClientConnectionOperator: can‘t find referenced class org.apache.commons.logging.LogFactory
 87  Warning: org.apache.http.impl.conn.DefaultClientConnectionOperator: can‘t find referenced class org.apache.commons.logging.LogFactory
 88  Warning: org.apache.http.impl.conn.DefaultHttpResponseParser: can‘t find referenced class org.apache.commons.logging.LogFactory
 89  Warning: org.apache.http.impl.conn.DefaultHttpResponseParser: can‘t find referenced class org.apache.commons.logging.LogFactory
 90  Warning: org.apache.http.impl.conn.DefaultResponseParser: can‘t find referenced class org.apache.commons.logging.LogFactory
 91  Warning: org.apache.http.impl.conn.DefaultResponseParser: can‘t find referenced class org.apache.commons.logging.LogFactory
 92  Warning: org.apache.http.impl.conn.IdleConnectionHandler: can‘t find referenced class org.apache.commons.logging.LogFactory
 93  Warning: org.apache.http.impl.conn.IdleConnectionHandler: can‘t find referenced class org.apache.commons.logging.LogFactory
 94  Warning: org.apache.http.impl.conn.InMemoryDnsResolver: can‘t find referenced class org.apache.commons.logging.LogFactory
 95  Warning: org.apache.http.impl.conn.InMemoryDnsResolver: can‘t find referenced class org.apache.commons.logging.LogFactory
 96  Warning: org.apache.http.impl.conn.PoolingClientConnectionManager: can‘t find referenced class org.apache.commons.logging.LogFactory
 97  Warning: org.apache.http.impl.conn.PoolingClientConnectionManager: can‘t find referenced class org.apache.commons.logging.LogFactory
 98  Warning: org.apache.http.impl.conn.SingleClientConnManager: can‘t find referenced class org.apache.commons.logging.LogFactory
 99  Warning: org.apache.http.impl.conn.SingleClientConnManager: can‘t find referenced class org.apache.commons.logging.LogFactory
100  Warning: org.apache.http.impl.conn.tsccm.AbstractConnPool: can‘t find referenced class org.apache.commons.logging.LogFactory
101  Warning: org.apache.http.impl.conn.tsccm.AbstractConnPool: can‘t find referenced class org.apache.commons.logging.LogFactory
102  Warning: org.apache.http.impl.conn.tsccm.ConnPoolByRoute: can‘t find referenced class org.apache.commons.logging.LogFactory
103  Warning: org.apache.http.impl.conn.tsccm.ConnPoolByRoute: can‘t find referenced class org.apache.commons.logging.LogFactory
104  Warning: org.apache.http.impl.conn.tsccm.RouteSpecificPool: can‘t find referenced class org.apache.commons.logging.LogFactory
105  Warning: org.apache.http.impl.conn.tsccm.RouteSpecificPool: can‘t find referenced class org.apache.commons.logging.LogFactory
106  Warning: org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager: can‘t find referenced class org.apache.commons.logging.LogFactory
107  Warning: org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager: can‘t find referenced class org.apache.commons.logging.LogFactory
108        You should check if you need to specify additional program jars.
109  Warning: there were 104 unresolved references to classes or interfaces.
110           You may need to specify additional library jars (using ‘-libraryjars‘).
111  Warning: there were 1 instances of library classes depending on program classes.
112           You must avoid such dependencies, since the program classes will
113           be processed, while the library classes will remain unchanged.
114  java.io.IOException: Please correct the above warnings first.
115      at proguard.Initializer.execute(Initializer.java:321)
116      at proguard.ProGuard.initialize(ProGuard.java:211)
117      at proguard.ProGuard.execute(ProGuard.java:86)
118      at proguard.ProGuard.main(ProGuard.java:492)

解决方法很简单,就是在proguard.cfg中加入句-dontwarn即可。

第二个运行时报错,我用真机调试查看了下LogCat日志输出,发现报的错误是找不到资源,而报错地方是引入第三方jar的时候,原来是混淆时将第三方jar包也混淆了,那么只要不混淆第三方jar就可以吧。

以下是我最后的proguard.cfg配置。

 

 1 -keep class **.R$* {   *;  }//不混淆R文件
 2 -optimizationpasses 5
 3 -dontusemixedcaseclassnames
 4 -dontskipnonpubliclibraryclasses
 5 -dontpreverify
 6 -ignorewarnings
 7 -verbose
 8 -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
 9 
10 //不混淆的jar包,脚本中去掉该句
11 -libraryjars libs/jar包名称
12 
13 -dontwarn//不警告,脚本中去掉该句
14 -dontskipnonpubliclibraryclassmembers
15 
16 -keep public class * extends android.app.Activity
17 -keep public class * extends android.app.Application
18 -keep public class * extends android.app.Service
19 -keep public class * extends android.content.BroadcastReceiver
20 -keep public class * extends android.content.ContentProvider
21 -keep public class * extends android.app.backup.BackupAgentHelper
22 -keep public class * extends android.preference.Preference
23 -keep public class com.android.vending.licensing.ILicensingService
24 
25 -keepclasseswithmembernames class * {
26     native <methods>;
27 }
28 
29 -keepclasseswithmembers class * {
30     public <init>(android.content.Context, android.util.AttributeSet);
31 }
32 
33 -keepclasseswithmembers class * {
34     public <init>(android.content.Context, android.util.AttributeSet, int);
35 }
36 
37 -keepclassmembers class * extends android.app.Activity {
38    public void *(android.view.View);
39 }
40 
41 -keepclassmembers enum * {
42     public static **[] values();
43     public static ** valueOf(java.lang.String);
44 }
45 
46 -keep class * implements android.os.Parcelable {
47   public static final android.os.Parcelable$Creator *;
48 }
49 
50 //不混淆某包中的指定内容,脚本中去掉该句
51 -keep class 包名.** {*;}

 

至此,就ok了

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。