1. 程式人生 > >Android studio aar 生成 和程式碼混淆

Android studio aar 生成 和程式碼混淆

本文主要講解如何將一個app模組改造生成一個帶介面資源的庫,也就是aar。
接著還講到,如何修改混淆配置,生成混淆後的aar。

1. aar 生成

1.1 build.gradle 檔案

  1. 模組是library不是 application
//apply plugin: 'com.android.application'
apply plugin: 'com.android.library'

2.註釋掉 applicationId

 //  applicationId "com.cmcc.iot.gatewaycloud"

在defaultConfig{}節點中去掉applicationId,versionCode,versionName等內容

  1. 如果有重新命名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 // } // } // }
  1. 如果有多渠道的,生成多渠道aar 是正常的,但是aar的專案以compile project(‘:xxxx’)方式使用的時候就必須去掉多渠道的,只能在defaultConfig 中將某一個渠道的程式碼拷貝上去,然後遮蔽掉其他所有渠道程式碼,否則以模組方式引用不到aar專案。

  2. 還需要我們在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);
}
  1. 注意 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);
}

3.參考連結