Android Studio实现打渠道包,切换环境,混淆配置等

2020-11-23 14:41:26 浏览数 (1)

最近遇到项目从Eclispe迁移到Android studio,以前的Ant自动打包脚本已经兼容不好了,所以用了Gradle实现打渠道包,切换环境等。

gradle的加入配置便宜版本报名,签名文件,配置打包生成apk文件名称规则,配置url,配置渠道所有的配置都是android {}中只进行的,配置一些关于android的基本配置。

温馨提示:代码部分可以左右滑动查看全部。

配置依赖资源

代码语言:javascript复制
 dependencies {
   compile fileTree(include: ['*.jar'], dir: 'libs')   testCompile 'junit:junit:4.12'
   compile 'com.android.support:appcompat-v7:23.2.1'
   compile 'com.android.support:support-v4:23.2.1'
   compile 'com.android.support:recyclerview-v7:23.2.1'
   .....
}

如果想兼容v4

代码语言:javascript复制
 compile ('com.android.support:recyclerview-v7:22.2.0'){ exclude module: 'support-v4' }

加载签名

代码语言:javascript复制
signingConfigs {    
   release {
        keyAlias props['KEY_ALIAS']
        keyPassword props['KEY_PASSWORD']
        storeFile file(props['KEYSTORE_FILE'])
        storePassword props['KEYSTORE_PASSWORD']
    }

    debug {
        storeFile file('../../debug.keystore')
        storePassword 'you pass'
        keyAlias 'you key'
        keyPassword 'you pass'
    }

}

加载签名配置文件

代码语言:javascript复制
Properties props = new Properties()
props.load(new FileInputStream(file("signing.properties")))

签名文件 signing.properties 配置如下:

代码语言:javascript复制
 KEY_ALIAS = xxxx
 KEY_PASSWORD = 你的密码
 KEYSTORE_FILE = ../../nide.keystroe (相对路径)
 KEYSTORE_PASSWORD =密码

签名你自己可生成,可以直接用eclispe生成的。

定义环境

定义线上环境Url

代码语言:javascript复制
def host_url = "https://xxx.com";

一些开关

开启混淆开关:

代码语言:javascript复制
minifyEnabled true

开启过滤非引用资源打包 :

代码语言:javascript复制
shrinkResources true

打开log输出:可以用field自定义属性,这里可以加个是否是debug,这样java代码可以直接用这个属性来做是否输出Log了。

代码语言:javascript复制
  buildConfigField "boolean", "LOG_DEBUG", "true"

定义打包方式:

代码语言:javascript复制
buildTypes {
     release {
        minifyEnabled true
        shrinkResources true
        buildConfigField "boolean", "LOG_DEBUG", "false"
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.release
    }


    debug {
        minifyEnabled true
        shrinkResources true
        buildConfigField "boolean", "LOG_DEBUG", "true"
        signingConfig signingConfigs.debug
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

编译项目后 会生成buildConfig文件

代码语言:javascript复制
 public final class BuildConfig {    
  public static final boolean DEBUG =      Boolean.parseBoolean("true");  // app id
  public static final String APPLICATION_ID = "com.skay.test";  public static final String BUILD_TYPE = "debug";  // 渠道
  public static final String FLAVOR = "dev";  // 版本
  public static final int VERSION_CODE = 1; public static final String VERSION_NAME = "1.0"; // Fields from the variant
  public static final String APP_ENV = "dev "; // host
  public static final String HOST_URL = " http://aaa.com/"; // Fields from build type: debug
  public static final boolean LOG_DEBUG = true;
}

代码中可以用Buidconfig.xxx的变量做一些逻辑判断。

配置打包脚本

可以定制化格式,在输出的apk加上渠道,时间,版本环境等。

代码语言:javascript复制
// 指定输出的apk名applicationVariants.all { 
    variant ->
    variant.outputs.each { output ->        
        def outputFile = output.outputFile       
         // 打包类型
        def buildTypeName = variant.buildType.name       
         if (outputFile != null && outputFile.name.endsWith('.apk')) {            // 包名称
            def flavorName = variant.productFlavors[0].name            
            // 版本名称
            def versionName = defaultConfig.versionName            
            // 开发环境
            buildConfigField "String", "APP_ENV", ""${flavorName} ""
            // 修改打包环境的url
            buildConfigField "String", "HOST_URL", "" ${host_url}""
            // yourapkname_release_myapk_ver1.0.0_build20130312.apk 输出格式
            def fileName = "${PRODUCT_NAME}_${buildTypeName}_${flavorName}_env${flavorName}_ver${versionName}_build${BUILD_TIME_FORMAT}.apk"

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

渠道配置

渠道用Flavors函数控制,可对应添加一些渠道。

代码语言:javascript复制
 //修改渠道号
 productFlavors {    // 线上版本 
     release{
     }     //开发版本,
     dev {
        host_url = "http://xxxx1.com./"

     }     //Qa测试版本
    qa{
         host_url = "http://xxx2.com/"
     }

}

这样我们在打包时 只要你开启你要的那个版本,buildConfig将会修改,输出包就可以了, 不仅切换了Url,而且还制定了渠道版本,非常方便。

添加对jar的支持

代码语言:javascript复制
有时候从eclispe移植过来时,返现jar无法加载,找不到地址

在android {}加入以下配置

代码语言:javascript复制
   sourceSets {
        main {
        jniLibs.srcDir 'libs'
      }    // Move the tests to tests/java, tests/res, etc...
    instrumentTest.setRoot('tests')    // Move the build types to build-types/<type>
    // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
    // This moves them out of them default location under src/<type>/... which would
    // conflict with src/ being used by the main source set.
    // Adding new build types or product flavors should be accompanied
    // by a similar customization.
    debug.setRoot('build-types/debug')
    release.setRoot('build-types/release')
}

添加NDK的兼容

如果so找不到 请配置对四个不同cpu的支持

在android {}加入以下配置

代码语言:javascript复制
 defaultConfig {
    .......

   ndk {
    abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
   }
}

配置混淆

配置proguard-rules.pro文件

代码语言:javascript复制
 # 混淆时不使用大小写混合,混淆后的类名为小写# windows下的同学还是加入这个选项吧(windows大小写不敏感)-dontusemixedcaseclassnames# 如果应用程序引入的有jar包,并且想混淆jar包里面的class-dontskipnonpubliclibraryclasses# 指定不去忽略非公共的库的类的成员-dontskipnonpubliclibraryclassmembers# 有了verbose这句话,混淆后就会生成映射文件# 包含有类名->混淆后类名的映射关系# 然后使用printmapping指定映射文件的名称
 -verbose
-ignorewarnings # Optimization is turned off by default. Dex does not like code run
 # through the ProGuard optimize and preverify steps (and   performs some
 # of these optimizations on its own).
 # 不做预检验,preverify是proguard的四个步骤之一
 # Android不需要preverify,去掉这一步可以加快混淆速度-dontpreverify# If you want to enable optimization, you should include the following:# 混淆采用的算法
 -optimizations  !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*# 设置混淆的压缩比率 0 ~ 7-optimizationpasses 5-allowaccessmodification# 保护代码中的Annotation不被混淆# 这在JSON实体映射时非常重要,比如fastJson-keepattributes *Annotation*# 避免混淆泛型
 # 这在JSON实体映射时非常重要,比如fastJson
 -keepattributes Signature  # 抛出异常时保留代码行号
 -keepattributes SourceFile,LineNumberTable # Add any project specific keep options here:
 # 保留了继承自Activity、Application这些类的子类
 # 因为这些子类有可能被外部调用
 # 比如第一行就保证了所有Activity的子类不要被混淆
 -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.view.View-keep public class * extends android.app.backup.BackupAgent
 -keep public class * extends  android.app.backup.BackupAgentHelper-keep public class * extends android.preference.Preference-keep public class * extends android.support.v4.app.Fragment-keep public class * extends android.app.Fragment-keep public class com.android.vending.licensing.ILicensingService# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native# 所有native的方法不能去混淆.
 -keepclasseswithmembernames class * {
    native <methods>;
 }# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations#  枚举类不能去混淆-keepclassmembers enum * {
   public static **[] values();
   public static ** valueOf(java.lang.String);
}# 某些构造方法不能去混淆-keepclasseswithmembers class * {
  public <init>(android.content.Context,  android.util.AttributeSet);
}

-keepclasseswithmembers class * {
   public <init>(android.content.Context, android.util.AttributeSet, int);
}# aidl文件不能去混淆.# 保留Parcelable序列化的类不能被混淆-keep class * implements android.os.Parcelable {
   public static final android.os.Parcelable$Creator *;
}# 保留Serializable 序列化的类不被混淆-keep class * implements java.io.Serializable {
    public *;
  }

 -keepclassmembers class * implements java.io.Serializable {
     static final long serialVersionUID;
    private static final java.io.ObjectStreamField[]   serialPersistentFields;
   !static !transient <fields>;
   private void writeObject(java.io.ObjectOutputStream);
   private void readObject(java.io.ObjectInputStream);
   java.lang.Object writeReplace();
   java.lang.Object readResolve();
}# 保留Activity中的方法参数是view的方法,# 从而我们在layout里面编写onClick就不会影响-keepclassmembers class * extends android.app.Activity {
    public void *(android.view.View);
}# 保留自定义控件(继承自View)不能被混淆-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*(...);
   public void get*(...);
} # 对R文件下的所有类及其方法,都不能被混淆
  -keepclassmembers class **.R$* {
      *;
  } # 对于带有回调函数onXXEvent的,不能混淆
 -keepclassmembers class * {
   void *(**On*Event);
}

常规混淆配置好,可以增加你项目中的混淆了,如数据模型bean,第三方sdk等.混淆也可以写个接口类,然让不混淆的类实现此接口比较简便,在gradle总直接配置不混淆的base即可。

代码语言:javascript复制
   -keep class com.baidu.pushsdk.** { *;}
   -keep class  com.mybisniss.mybean.** { *;}

总结

以上是是通常的gradle打包过程中遇到的注意事项,大致能满足初学者对as的需求。

推荐

Gradle敏捷打包,多版本,多渠道,多环境,多功能,多模块随心所欲

开发者技术前线

END

0 人点赞