編輯:關於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$* {
public static ;
}
....
這樣之後,就要去混淆文件中去加混淆代碼了。(混淆代碼在文章末尾貼出),我直接說遇到的問題。
打包時遇到了這樣的錯誤
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了我的適配器包。然後不報錯了。
但是還沒有結束
第三方登錄,和分享功能不能用!!!因為用的友盟分享和第三方登錄。
#友盟混淆
-keep class com.umeng.**
-keep class com.umeng.**{*;}
這樣看來,混淆其實也很簡單,最主要是找到問題,解決問題。
最後獻上混淆源碼
#指定代碼的壓縮級別
-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 (android.content.Context);
public (android.content.Context, android.util.AttributeSet);
public (android.content.Context, android.util.AttributeSet, int);
public void set*(...);
}
#保持 native 方法不被混淆
-keepclasseswithmembernames class * {
native ;
}
# Keep names - Native method names. Keep all native class/method names.
-keepclasseswithmembers,allowshrinking class * {
native ;
}
#保持自定義控件類不被混淆
-keepclasseswithmembers class * {
public (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 ;
!private ;
!private ;
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 ;
}
#不混淆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
Android 筆記-Fragment 與 Activity之間傳遞數據
Fragment 與 Activity之間傳遞數據有兩種方法,一種是使用setArgument,一種是使用接口回調。下面先學習第一種方法。 (1)使用setArgum
ListView分割線
重新定義分割線Drawable的Bounds首先,需要清楚一個事實:出現以上情況的矛盾點,是官方ListView的分割線屬性不支持左右留白。所以最佳的解決方案,就是使得官
Android中如何修改編譯的資源ID值(默認值是0x7F...可以隨意改成0x02~0x7E)
一、技術准備今天我們來看一下如何修改Android中編譯時的資源Id的值,在講解這內容之前,我們需要先了解一下Android中的資源編譯之後的結構和編譯過程,這裡就不多說
Android仿京東首頁輪播文字(又名垂直跑馬燈)
京東客戶端的輪播文字效果: 本次要實現的只是後面滾動的文字(前面的用ImageView或者TextView實現即可),看一下實現的效果 實