前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android Studio实现打渠道包,切换环境,混淆配置等

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

作者头像
开发者技术前线
发布2020-11-23 14:41:26
1.2K0
发布2020-11-23 14:41:26
举报

最近遇到项目从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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-03-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开发者技术前线 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档