安卓 代碼混淆與打包


代碼混淆部分

gradle的配置

minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'

proguard-rules.pro混淆配置

###-----------基本配置-不能被混淆的------------
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Fragment
-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

#support.v4/v7包不混淆
-keep class android.support.** { *; }
-keep class android.support.v4.** { *; }
-keep public class * extends android.support.v4.**
-keep interface android.support.v4.app.** { *; }
-keep class android.support.v7.** { *; }
-keep public class * extends android.support.v7.**
-keep interface android.support.v7.app.** { *; }
-dontwarn android.support.**    # 忽略警告

#保持注解繼承類不混淆
-keep class * extends java.lang.annotation.Annotation {*;}
#保持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;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}
#保持枚舉enum類不被混淆
-keepclassmembers enum * {
  public static **[] values();
 public static ** valueOf(java.lang.String);
}
#自定義組件不被混淆
-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}

#不混淆資源類
-keepclassmembers class **.R$* {
    public static <fields>;
}

###-----------第三方jar包library混淆配置------------
#ormlite混淆配置
#-libraryjars libs/ormlite-android-5.0.jar
#-libraryjars libs/ormlite-core-5.0.jar
-dontwarn com.j256.ormlite.**
-keep class com.j256.ormlite.** { *;}
-keep class com.envy15.cherry.base.orm.** { *;}
#json-lib混淆配置
#-libraryjars libs/json-lib-2.4-jdk15.jar
-dontwarn net.sf.json.**
-keep class net.sf.json.** { *;}
#json-lib關聯包
#-libraryjars libs/commons-beanutils-1.8.3.jar
-dontwarn org.apache.commons.**
-keep class org.apache.commons.** { *;}
#universalimageloader圖片加載框架不混淆
-keep class com.nostra13.universalimageloader.** { *; }
-dontwarn com.nostra13.universalimageloader.**
#Gson相關的不混淆配置
-keepattributes Signature
-keepattributes *Annotation*
-keep class com.google.gson.** { *; }
-dontwarn com.google.gson.**
-keep class com.envy15.cherry.fragment.crossover.model.** { *; }
-dontwarn com.envy15.cherry.fragment.crossover.model.**
-keep class com.envy15.cherry.fragment.discover.model.** { *; }
-dontwarn com.envy15.cherry.fragment.discover.model.**
-keep class com.envy15.cherry.fragment.local.model.** { *; }
-dontwarn com.envy15.cherry.fragment.local.model.**
-keep class com.envy15.cherry.fragment.setting.model.** { *; }
-dontwarn com.envy15.cherry.fragment.setting.model.**
#prt-lib下拉刷新框架不混淆
-keep class in.srain.cube.views.ptr.** { *; }
-dontwarn in.srain.cube.views.ptr.**
#PullToRefreshLibrary下拉刷新框架不混淆
-keep class com.handmark.pulltorefresh.library.** { *; }
-dontwarn com.handmark.pulltorefresh.library.**

#參考:
#  http://blog.csdn.net/zuiwuyuan/article/details/48552701
#  http://blog.csdn.net/fengyuzhengfan/article/details/43876197
#  http://blog.isming.me/2014/05/31/use-proguard/
#  http://hanhailong.com/2015/12/28/Android%E8%BF%9B%E9%98%B6%E4%B9%8BProGuard%E4%BB%A3%E7%A0%81%E6%B7%B7%E6%B7%86/
# 關於混淆的思考:
#  https://www.zhihu.com/question/37446729
# 擴展:資源文件混淆
#  http://blog.csdn.net/Fancy_xty/article/details/51202866
#代碼混淆規則
# 指定代碼的壓縮級別
#-optimizationpasses 5
# 是否使用大小寫混合
#-dontusemixedcaseclassnames
# 是否混淆第三方jar
#-dontskipnonpubliclibraryclasses
# 混淆時是否做預校驗
#-dontpreverify
# 混淆時是否記錄日志
#-verbose
# 混淆時所采用的算法
#-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

#-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 方法不被混淆
#    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 * {                                                      # 保持枚舉 enum 類不被混淆
#    public static **[] values();
#    public static ** valueOf(java.lang.String);
#}
#
#-keep class * implements android.os.Parcelable {                                # 保持 Parcelable 不被混淆
#  public static final android.os.Parcelable$Creator *;
#}

#-keep class MyClass;                                                            # 保持自己定義的類不被混淆

 

打包發布部分

S1.使用默認方式打包簽名APK

AndroidStudio選擇Build => Generate Signed APK

總體步驟流程如下:

詳細操作步驟:

S2. 多渠道打包APK

屬性配置

productFlavors

    productFlavors {

        aVer {

            resValue("string","strKey","myKey")

            applicationId "com.simple.pkg.debug"

        }

        bVer {

            applicationId "com.simple.pkg.beta"

        }

        cVer {

            applicationId "com.simple.pkg.res"

        }

    }

signingConfigs

    signingConfigs {

        release {

            storeFile file('E:/XXX/app.jks') // 簽名證書文件

            storePassword 'you password' // 證書密碼

            keyAlias 'test'

            keyPassword 'you password '

        }

    }

buildTypes

    buildTypes {

        mbeta {

            signingConfig android.signingConfigs.release

            minifyEnabled false

        }

    }

 

S3.gradle打包自動化-定制apk文件名

gradle屬性及變量定義的幾種方式

變量定義

方式1(for gradle)

工程目錄下gradle.properties定義屬性:appName = MyAppName

App目錄下build.gradle讀取自定義屬性:project.appName

方式2(for java)

App目錄下build.gradle定義屬性:

    productFlavors {

        aVer {

            // gradle定義全局變量方式2-代碼使用

            buildConfigField "int", "varInt", "0"

            buildConfigField "String", "varString", '"abc"'

        }

}

Java代碼讀取屬性:BuildConfig.varInt;BuildConfig.varString;

方式3(for java)

App目錄下build.gradle定義屬性:

    productFlavors {

        aVer {

            resValue("string","strKey","myKey")

        }

}

ava代碼讀取屬性:context.getString(R.string.strKey);

方式4

App目錄下build.gradle定義屬性:

def flavorName = "undefine"

def indexFlavor(String str) {

    return str.substring(0,str.length())

}

方式5

App目錄AndroidManifest.xml定義變量

        <meta-data

            android:name="env_key0"

            android:value="${env_val0}" />

build.gradle修改env_val0

    buildTypes {

        debug {

            minifyEnabled false

            manifestPlaceholders = [env_val0: "VAL0", env_val1: "VAL1"]

        }

    }

Java代碼中獲取meta屬性定義

    public static String getMetaValue(Context context,String key){

        ApplicationInfo applicationInfo = null;

        try {

            applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);

        } catch (PackageManager.NameNotFoundException e) {

            e.printStackTrace();

        }

        if (applicationInfo == null){

            return "";

        }

        return applicationInfo.metaData.getString(key);

    }

 

Ref:

     android studio gradle 多版本多apk打包(打包系列教程之五)

     Gradle 自定義構建全局變量

     android studio 自定義gradle變量

 

定制apk文件名

變量定義

自定義生成APK文件名

applicationVariants.all { variant ->

variant.outputs.each { output ->

def outputFile = output.outputFile

         // appName + version + createTime + svnVersion + flavor + buildType

         def fileName = "fileName.apk"

         output.outputFile = new File(outputFile.parent, fileName)

       }

    }

獲取相關屬性

AppName:自定義方式或getName()

Version:版本, defaultConfig.versionName

CreateTime:創建時間,new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))

SvnVersion :SVN提交版本號
Flavor :編譯渠道版本

BuildType:debug/beta/release版本

def fileName = "${project.appName}_v${defaultConfig.versionName}_${releaseTime()}_" +

                            "s${getSvnRevision()}_${indexFlavor(productFlavors.name)}_${getName()}.apk"

 

 

Ref:

     Android Gradle實用技巧——APK文件名中加上SVN版本號,日期等

     Android 使用Gradle打包APP名稱和版本號

 

參考問題:

     buildTypes中加上signingConfig sigingConfigs.release運行就報錯

build.gradle多渠道打包完整示例

// app/build.gradle文件
import org.tmatesoft.svn.core.wc.* // for svn version
apply plugin: 'com.android.application'
def releaseTime() {
    return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
}
def indexFlavor(String str) {
    return str.substring(0,str.length())
}
def getSvnRevision() { // for svn
    ISVNOptions options = SVNWCUtil.createDefaultOptions(true);
    SVNClientManager clientManager = SVNClientManager.newInstance(options);
    SVNStatusClient statusClient = clientManager.getStatusClient();
    SVNStatus status = statusClient.doStatus(projectDir, false);
    SVNRevision revision = status.getCommittedRevision();
    return revision.getNumber();
}
android {
    signingConfigs {
    }
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.simple.res"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
        multiDexEnabled true    // dex突破65535的限制
    }
    productFlavors {
        aVer {
            // gradle定義全局變量方式2-代碼使用
            buildConfigField "int", "varInt", "0"
            buildConfigField "String", "varString", '"abc"'
            //
            resValue("string","strKey","myKey")
            applicationId "com.simple.res.debug"
        }
        bVer {
            applicationId "com.simple.res.beta"
        }
    }
    signingConfigs {
        release {
            storeFile file('E:/XXX/App.jks')
            storePassword 'you password'
            keyAlias 'TEST'
            keyPassword 'you password'
        }
    }
    buildTypes {
        debug {
            minifyEnabled false
        }
        mbeta {
            signingConfig android.signingConfigs.release
            minifyEnabled false
        }
        release {
            signingConfig android.signingConfigs.release
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            minifyEnabled true
            shrinkResources true
            // 指定APK文件名
            applicationVariants.all { variant ->
                variant.outputs.each { output ->
                    def outputFile = output.outputFile
                    // appName + version + createTime + svnVersion + flavor + buildType
                    def fileName = "${project.appName}_v${defaultConfig.versionName}_${releaseTime()}_" + "s${getSvnRevision()}_${indexFlavor(productFlavors.name)}_${getName()}.apk"
                    output.outputFile = new File(outputFile.parent, fileName)
                }
            }
        }
    }
}
// project/build.gradle文件
// 添加classpath group: 'org.tmatesoft.svnkit', name: 'svnkit', version: '1.8.11'支持獲取// SVN提交版本號
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.3'
        classpath group: 'org.tmatesoft.svnkit', name: 'svnkit', version: '1.8.11'
}
// project/build.gradle文件
appName = NewApp

 

 * 崩潰日志記錄
 * 參考:
 *  http://blog.csdn.net/u012333411/artile/details/49019415
 *  http://blog.csdn.net/wangyuexing_blog/article/details/39009069

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM