Android studio aar 生成 和程式碼混淆
本文主要講解如何將一個app模組改造生成一個帶介面資源的庫,也就是aar。
接著還講到,如何修改混淆配置,生成混淆後的aar。
1. aar 生成
1.1 build.gradle 檔案
- 模組是library不是 application
//apply plugin: 'com.android.application'
apply plugin: 'com.android.library'
2.註釋掉 applicationId
// applicationId "com.cmcc.iot.gatewaycloud"
在defaultConfig{}節點中去掉applicationId,versionCode,versionName等內容
- 如果有重新命名apk 的腳步,也需要註釋掉
// applicationVariants.all {
// variant ->
// variant.outputs.each {
// output ->
// def outputFile = output.outputFile
// if (outputFile != null && outputFile.name.endsWith('.apk')) {
// def fileName = new File(output.outputFile.parent, "${variant.flavorName}" + "-v" + "${variant.versionName}-${variant.versionCode}.apk")
// output.outputFile = fileName
// }
// }
// }
如果有多渠道的,生成多渠道aar 是正常的,但是aar的專案以compile project(‘:xxxx’)方式使用的時候就必須去掉多渠道的,只能在defaultConfig 中將某一個渠道的程式碼拷貝上去,然後遮蔽掉其他所有渠道程式碼,否則以模組方式引用不到aar專案。
還需要我們在manifest的application標籤的主活動中去掉
6.一般情況下,我們還需要去掉
android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/ColorTranslucentTheme"
等內容,防止在引用的時候發生衝突!
或者在引用aar包的專案的application標籤下新增:
tools:replace=”android:icon,android:name,android:label,android:allowBackup,android:theme”>,解決衝突!
1.2 修改完指令碼,點選Sync Now 按鈕 就可以生成aar檔案了
aar的生成路徑在:app/build/outputs/aar/xxxx.aar
如果是有多渠道版本的話,這個生成的版本是通過Build Variant 選擇的版本生成的,如下:
或者在Android studio下方的Terminal 下輸入命令列執行構建aar
gradle build
執行上面一行命令,就可以生成aar,如果有多渠道的話,所有版本的debug release 版本的aar都會生成。
1.3 引用arr包
①跟引入jar包一樣,將aar檔案拷貝到app/libs目錄下
②在gradle根節點新增如下程式碼:
repositories{
flatDir{
dirs ‘libs’
}
}
③最後在dependencies{}標籤下進行關聯:
compile (name: ‘你引入的aar檔案的名稱,不包含字尾’, ext: ‘aar’)
2. aar混淆
2.1 build.gradle修改
buildTypes {
release {
//簽名
signingConfig signingConfigs.myConfig
//混淆
minifyEnabled true
//對齊
zipAlignEnabled true
//移除無用的resource 檔案
shrinkResources true
//載入預設混淆配置檔案
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
在release版本中,混淆、對齊、移除無用的resource 檔案都改成true。
2.2 混淆配置檔案修改
主要以下幾種情況需要配置是否混淆程式碼;
1.保持專案中的第三方jar不混淆
如極光推送,gson包,百度定位,自研的jar 檔案,這些都需要新增不混淆程式碼的配置
極光:
#JPush
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
#==================gson==========================
-dontwarn com.google.**
-keep class com.google.gson.** {*;}
#==================protobuf======================
-dontwarn com.google.**
-keep class com.google.protobuf.** {*;}
百度:
#baidu location
-keep class com.baidu.** { *; }
-keep class vi.com.gdi.bgl.android.**{*;}
#baidu location
2.保持Activity Fragment ,自定義控制元件不混淆
# 保持哪些類不被混淆
-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
#如果有引用v4包可以新增下面這行
-keep public class * extends android.support.v4.app.Fragment
-keepclasseswithmembers class * { # 保持自定義控制元件類不被混淆
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {# 保持自定義控制元件類不被混淆
public <init>(android.content.Context, android.util.AttributeSet, int);
}
- 注意 gson 物件的序列化,以及內部類的混淆
4.內部介面一般也需要keep,如果內部介面需要外面引用的話,最好單獨定義個類;
5.一般外面需要呼叫的介面,都需要keep
2.3 我的例子:
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/jacky/Documents/Android_env/eclipse_env/android-sdk-macosx/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-ignorewarnings
-dontnote android.net.http.*
-dontnote org.apache.commons.codec.**
-dontnote org.apache.http.**
# webview + js
-keepattributes *JavascriptInterface*
# keep 使用 webview 的類
-keepclassmembers class com.cmcc.iot.gatewaycloud.PluginCenterWebviewActivity {
public *;
}
# keep 使用 webview 的類的所有的內部類
-keepclassmembers class com.cmcc.iot.gatewaycloud.PluginCenterWebviewActivity*{
*;
}
# keep 使用 webview 的類
-keepclassmembers class com.cmcc.iot.gatewaycloud.PluginCenterWebviewActivity {
public *;
}
# keep 使用 webview 的類的所有的內部類
-keepclassmembers class com.cmcc.iot.gatewaycloud.PluginCenterWebviewActivity*{
*;
}
#JPush
-dontwarn cn.jpush.**
-keep class cn.jpush.** { *; }
#==================gson==========================
-dontwarn com.google.**
-keep class com.google.gson.** {*;}
#==================protobuf======================
-dontwarn com.google.**
-keep class com.google.protobuf.** {*;}
#################### region for xUtils
-keepattributes Signature,*Annotation*
-keep public class org.xutils.** {
public protected *;
}
-keep public interface org.xutils.** {
public protected *;
}
-keepclassmembers class * extends org.xutils.** {
public protected *;
}
-keepclassmembers @org.xutils.db.annotation.* class * {*;}
-keepclassmembers @org.xutils.http.annotation.* class * {*;}
-keepclassmembers class * {
@org.xutils.view.annotation.Event <methods>;
}
##################### end region
#
##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.cmcc.iot.gatewaycloud.http.bean.request.** { *; }
-keep class com.cmcc.iot.gatewaycloud.http.bean.response.** { *; }
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,Annotation,EnclosingMethod
-keep class com.cmcc.iot.gatewaycloud.http.bean.request.**$*{ *; }
-keep class com.cmcc.iot.gatewaycloud.http.bean.response.**$*{ *; }
# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
-keep public class * implements java.io.Serializable {*;}
#baidu location
-keep class com.baidu.** { *; }
-keep class vi.com.gdi.bgl.android.**{*;}
#baidu location
# 保持哪些類不被混淆
-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
#如果有引用v4包可以新增下面這行
-keep public class * extends android.support.v4.app.Fragment
-keepclasseswithmembers class * { # 保持自定義控制元件類不被混淆
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {# 保持自定義控制元件類不被混淆
public <init>(android.content.Context, android.util.AttributeSet, int);
}