歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

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包。

所報錯誤如下

Proguard returned with error code 1. See console
 Note: there were 1465 duplicate class definitions.
 Warning: library class android.net.http.AndroidHttpClient extends or implements program class org.apache.http.client.HttpClient
 Warning: org.apache.http.client.protocol.RequestAddCookies: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.client.protocol.RequestAddCookies: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.client.protocol.RequestAuthCache: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.client.protocol.RequestAuthCache: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.client.protocol.RequestAuthenticationBase: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.client.protocol.RequestAuthenticationBase: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.client.protocol.RequestClientConnControl: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.client.protocol.RequestClientConnControl: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.client.protocol.ResponseAuthCache: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.client.protocol.ResponseAuthCache: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.client.protocol.ResponseProcessCookies: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.client.protocol.ResponseProcessCookies: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.auth.BasicScheme: can't find referenced class org.apache.commons.codec.binary.Base64
 Warning: org.apache.http.impl.auth.BasicScheme: can't find referenced class org.apache.commons.codec.binary.Base64
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.apache.commons.codec.binary.Base64
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.apache.commons.codec.binary.Base64
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSManager
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSName
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSManager
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSName
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSManager
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSContext
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSContext
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSContext
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSException
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSException
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSException
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.apache.commons.codec.binary.Base64
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.apache.commons.codec.binary.Base64
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSManager
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSName
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSContext
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.apache.commons.codec.binary.Base64
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSManager
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.Oid
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.Oid
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSManager
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSName
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSContext
 Warning: org.apache.http.impl.auth.GGSSchemeBase: can't find referenced class org.ietf.jgss.GSSException
 Warning: org.apache.http.impl.auth.KerberosScheme: can't find referenced class org.ietf.jgss.Oid
 Warning: org.apache.http.impl.auth.KerberosScheme: can't find referenced class org.ietf.jgss.Oid
 Warning: org.apache.http.impl.auth.KerberosScheme: can't find referenced class org.ietf.jgss.GSSException
 Warning: org.apache.http.impl.auth.NTLMEngineImpl$NTLMMessage: can't find referenced class org.apache.commons.codec.binary.Base64
 Warning: org.apache.http.impl.auth.NTLMEngineImpl$NTLMMessage: can't find referenced class org.apache.commons.codec.binary.Base64
 Warning: org.apache.http.impl.auth.NTLMEngineImpl$NTLMMessage: can't find referenced class org.apache.commons.codec.binary.Base64
 Warning: org.apache.http.impl.auth.NegotiateScheme: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.auth.NegotiateScheme: can't find referenced class org.ietf.jgss.Oid
 Warning: org.apache.http.impl.auth.NegotiateScheme: can't find referenced class org.ietf.jgss.Oid
 Warning: org.apache.http.impl.auth.NegotiateScheme: can't find referenced class org.ietf.jgss.GSSException
 Warning: org.apache.http.impl.auth.NegotiateScheme: can't find referenced class org.ietf.jgss.GSSException
 Warning: org.apache.http.impl.auth.NegotiateScheme: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.auth.NegotiateScheme: can't find referenced class org.ietf.jgss.GSSException
 Warning: org.apache.http.impl.auth.NegotiateScheme: can't find referenced class org.ietf.jgss.Oid
 Warning: org.apache.http.impl.auth.SPNegoScheme: can't find referenced class org.ietf.jgss.Oid
 Warning: org.apache.http.impl.auth.SPNegoScheme: can't find referenced class org.ietf.jgss.Oid
 Warning: org.apache.http.impl.auth.SPNegoScheme: can't find referenced class org.ietf.jgss.GSSException
 Warning: org.apache.http.impl.client.AbstractAuthenticationHandler: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.AbstractAuthenticationHandler: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.AbstractHttpClient: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.AbstractHttpClient: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.AuthenticationStrategyAdaptor: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.AuthenticationStrategyAdaptor: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.AuthenticationStrategyImpl: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.AuthenticationStrategyImpl: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.AutoRetryHttpClient: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.AutoRetryHttpClient: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.DefaultRedirectHandler: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.DefaultRedirectHandler: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.DefaultRedirectStrategy: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.DefaultRedirectStrategy: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.DefaultRequestDirector: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.DefaultRequestDirector: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.HttpAuthenticator: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.client.HttpAuthenticator: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.BasicClientConnectionManager: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.BasicClientConnectionManager: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.DefaultClientConnection: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.DefaultClientConnection: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.DefaultClientConnection: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.DefaultClientConnectionOperator: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.DefaultClientConnectionOperator: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.DefaultHttpResponseParser: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.DefaultHttpResponseParser: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.DefaultResponseParser: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.DefaultResponseParser: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.IdleConnectionHandler: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.IdleConnectionHandler: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.InMemoryDnsResolver: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.InMemoryDnsResolver: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.PoolingClientConnectionManager: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.PoolingClientConnectionManager: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.SingleClientConnManager: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.SingleClientConnManager: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.tsccm.AbstractConnPool: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.tsccm.AbstractConnPool: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.tsccm.ConnPoolByRoute: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.tsccm.ConnPoolByRoute: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.tsccm.RouteSpecificPool: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.tsccm.RouteSpecificPool: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager: can't find referenced class org.apache.commons.logging.LogFactory
 Warning: org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager: can't find referenced class org.apache.commons.logging.LogFactory
      You should check if you need to specify additional program jars.
 Warning: there were 104 unresolved references to classes or interfaces.
          You may need to specify additional library jars (using '-libraryjars').
 Warning: there were 1 instances of library classes depending on program classes.
          You must avoid such dependencies, since the program classes will
          be processed, while the library classes will remain unchanged.
 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)

解決方法很簡單,就是在proguard.cfg中加入句-dontwarn即可。

第二個運行時報錯,我用真機調試查看了下LogCat日志輸出,發現報的錯誤是找不到資源,而報錯地方是引入第三方jar的時候,原來是混淆時將第三方jar包也混淆了,那麼只要不混淆第三方jar就可以吧。

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

-keep class **.R$* {  *;  }//不混淆R文件
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-ignorewarnings
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

//不混淆的jar包,腳本中去掉該句
-libraryjars libs/jar包名稱

-dontwarn//不警告,腳本中去掉該句
-dontskipnonpubliclibraryclassmembers

-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

-keepclasseswithmembernames class * {
    native <methods>;
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers class * extends android.app.Activity {
  public void *(android.view.View);
}

-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

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

//不混淆某包中的指定內容,腳本中去掉該句
-keep class 包名.** {*;}

至此,就ok了

更多Android相關信息見Android 專題頁面 http://www.linuxidc.com/topicnews.aspx?tid=11

Copyright © Linux教程網 All Rights Reserved