博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
安卓 代码混淆与打包
阅读量:5101 次
发布时间:2019-06-13

本文共 11365 字,大约阅读时间需要 37 分钟。

代码混淆部分

gradle的配置

minifyEnabled trueproguardFiles 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 
(android.content.Context); public
(android.content.Context, android.util.AttributeSet); public
(android.content.Context, android.util.AttributeSet, int); public void set*(...);}#不混淆资源类-keepclassmembers class **.R$* { public static
;}###-----------第三方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
;#}##-keepclasseswithmembers class * { # 保持自定义控件类不被混淆# public
(android.content.Context, android.util.AttributeSet);#}##-keepclasseswithmembers class * {# public
(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:

    

    

    

 

定制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:

    

    

 

参考问题:

    

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

// app/build.gradle文件import org.tmatesoft.svn.core.wc.* // for svn versionapply 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

  

  

转载于:https://www.cnblogs.com/zhen-android/p/6014336.html

你可能感兴趣的文章
Html5 离线页面缓存
查看>>
[php]在PHP中读取和写入WORD文档的代码
查看>>
WCF傻瓜模式写程序
查看>>
《绿色·精简·性感·迷你版》易语言,小到不可想象
查看>>
Java Web学习总结(13)Listener监听器
查看>>
开始Flask项目
查看>>
Ruby:多线程队列(Queue)下载博客文章到本地
查看>>
Android打包key密码丢失找回
查看>>
03 jQuery动画
查看>>
医药箱APP静态小项目
查看>>
安装使用eclipse
查看>>
VC6.0调试技巧(一)(转)
查看>>
linux命令
查看>>
类库与框架,强类型与弱类型的闲聊
查看>>
webView添加头视图
查看>>
php match_model的简单使用
查看>>
在NT中直接访问物理内存
查看>>
Intel HEX 文件格式
查看>>
SIP服务器性能测试工具SIPp使用指导(转)
查看>>
php_扑克类
查看>>