android - build.gradle
16lz
2021-01-23
app
apply plugin: 'com.android.application'apply plugin: 'findbugs'//得到日期的方法static def releaseTime() { return new Date().format("yyMMdd-HHmm")}//基本配置android { compileSdkVersion 26 buildToolsVersion '26.0.2' defaultConfig { applicationId "com.guangyouqian.app" minSdkVersion 15 targetSdkVersion 26 versionCode 1000100 versionName "1.0.1" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" manifestPlaceholders = [channel:"weiliu"] }//签名信息配置 signingConfigs { release { storeFile file("keystore.jks") storePassword "xxxxxxxxxxxx"//密码 keyAlias "xxxx"//名称 keyPassword "xxxxxxxxxxx"//密码 } }//编译的类型 buildTypes { release { // BuildConfig类下增加自定义字段 参数的含义(类型,名称,内容) buildConfigField "boolean", "DEV", "false" buildConfigField "String", "API_HOST", "\"https://api.gyq.v6h5.com/\"" //选择签名信息 signingConfig signingConfigs.release //会对代码进行混淆和压缩 minifyEnabled true //会对比R文件对无用资源进行删除 (minifyEnabled 设置为true时shrinkResources 的设置才会生效) shrinkResources true //是否启用zipAlign压缩 zipAlignEnabled true //用到的混淆文件 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } http { matchingFallbacks = ['debug', 'release'] buildConfigField "boolean", "DEV", "true" debuggable true signingConfig signingConfigs.release minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { buildConfigField "boolean", "DEV", "true" debuggable true signingConfig signingConfigs.release minifyEnabled false shrinkResources false } } lintOptions { abortOnError false lintConfig file('lint.xml') }//打包apk重命名// android.applicationVariants.all { variant ->// variant.outputs.all { output ->// def channel = defaultConfig.manifestPlaceholders.get("channel")// if (variant.buildType.name == 'release' && outputFileName != null && outputFileName.endsWith('.apk')) {// //这里修改apk文件名// outputFileName = "gyq-${channel}-v${defaultConfig.versionName}-${releaseTime()}.apk"// }// }// } externalNativeBuild { ndkBuild { path 'src/main/jni/Android.mk' } }}//依赖配置dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile project(':library') testCompile 'junit:junit:4.12'}static def getAppName() { return "czsp"}static def originReleaseApk() { return getAppName() + "-release.apk"}static def andResGuardApk() { return "AndResGuard_app-release/app-release_aligned_signed.apk"}def timeReleaseApkName() { String appVersion = project.android.defaultConfig.versionName return String.format(getAppName() + "-%s-%s", appVersion, releaseTime())}afterEvaluate { // daily build,会自动通过findbugs工具检查代码并输出结果 //noinspection GroovyAssignabilityCheck task dailyBuild(dependsOn: 'assemble', type: FindBugs) { ignoreFailures = true reportLevel = "medium" classes = files("$project.buildDir/intermediates/classes")// Use this only if you want exclude some errors excludeFilter = file("findbugs_exclude.xml") source = fileTree(dir: '../', include: '*/src/main/**/*.java') classpath = files() reports { xml.enabled = true xml.withMessages = true html.enabled = !xml.isEnabled() //noinspection GroovyAssignabilityCheck xml.destination "$project.buildDir/outputs/findbugs/findbugs-output.xml" html.destination "$project.buildDir/outputs/findbugs/findbugs-output.html" } } task channelBuild { String dir = "../repack/" + project.android.defaultConfig.versionName String path = dir + "/" + getAppName() + ".apk"; println "-apkPath = " + file(path).getAbsolutePath() boolean apkRebuild = project.hasProperty("apkRebuild") ? project.property("apkRebuild").toBoolean() : false println "-apkRebuild = " + apkRebuild boolean shouldRebuild = apkRebuild || !file(path).exists() println "shouldRebuild = " + shouldRebuild if (shouldRebuild) { //构建build那个包 dependsOn 'assembleRelease' //或者assembleDebug . resguardRelease .... } doFirst { println "doFirst shouldRebuild = " + shouldRebuild println "doFirst path = " + path if (shouldRebuild) { if (file(path).exists()) { if (!file(path).delete()) { println "delete " + path + " failed" throw new RuntimeException("delete " + path + " failed") } } else { file(path).getParentFile().mkdirs() } //将源发布的app,复制一份到指定的位置 ,originReleaseApk()源app , renameTo()就是复制方法 file(path) 目标路径 if (file("$project.buildDir/outputs/apk/release/" + originReleaseApk()).renameTo(file(path))) { println "renameTo " + path + " success" } else { println "renameTo " + path + "failed" throw new RuntimeException("renameTo " + path + " failed") } } } doLast { def localProperties = new File(rootDir, "local.properties") Properties properties = new Properties() localProperties.withInputStream { instr -> properties.load(instr) } def sdkDir = properties.getProperty('sdk.dir') // apktool decode String apktool = "apktool-cli.jar" String apktoolDecodeDir = dir + "/apktool_decode" if (shouldRebuild || !file(apktoolDecodeDir).exists()) { if (!file(apktoolDecodeDir).exists()) { if (!file(apktoolDecodeDir).mkdir()) { println "mkdir " + apktoolDecodeDir + " failed" throw new RuntimeException("mkdir " + apktoolDecodeDir + " failed") } } println "apktool decode to " + apktoolDecodeDir + " starting......" exec { executable "java" args "-jar", apktool, "d", "-f", "-r", "-s", "-o", apktoolDecodeDir, path } println "apktool decode to " + apktoolDecodeDir + " end" } // for channels if (!project.hasProperty("channels")) { println "no channels1" throw new StopExecutionException() } String[] channels = project.property("channels").split(",") if (channels == null || channels.length == 0) { println "no channels2" throw new StopExecutionException() } String buildNo = project.hasProperty("buildNo") ? project.property("buildNo") : "undefined" String buildNoDir = dir + "/" + buildNo if (!file(buildNoDir).exists()) { if (!file(buildNoDir).mkdir()) { println "mkdir " + buildNoDir + " failed" throw new RuntimeException("mkdir " + buildNoDir + " failed") } } String finalName = timeReleaseApkName() String apktoolBuildTempPath = dir + "/" + finalName + "_unsigned.apk" String signTempPath = dir + "/" + finalName + "_unaligned.apk" String[] paths = [apktoolBuildTempPath, signTempPath] for (String filePath : paths) { if (file(filePath).exists() && !file(filePath).delete()) { println "delete " + filePath + " failed" throw new RuntimeException("delete " + filePath + " failed") } } for (String channel : channels) { String finalApkPath = buildNoDir + "/" + finalName + "_" + channel + ".apk"// def manifestFile = file(apktoolDecodeDir + "/AndroidManifest.xml")// println channel + " write to " + manifestFile + " starting..."// def content = manifestFile.getText()// def replace = content.replaceAll(/(android:name="UMENG_CHANNEL"\s+android:value=")(\w+)(")/, '$1' + channel + '$3')// manifestFile.write replace String channelFilePath = apktoolDecodeDir + "/assets/channel.ini" println channel + " write to " + channelFilePath + " starting..." file(channelFilePath).write channel println apktoolBuildTempPath + " apktool build starting..." exec { executable "java" args "-jar", apktool, "b", "-f", "-o", apktoolBuildTempPath, apktoolDecodeDir } println signTempPath + " jarsigner sign starting..." exec { executable "jarsigner" args "-keystore", project.android.signingConfigs.release.storeFile, "-storepass", project.android.signingConfigs.release.storePassword, "-keypass", project.android.signingConfigs.release.keyPassword, "-digestalg", "SHA1", "-sigalg", "MD5withRSA", "-signedjar", signTempPath, apktoolBuildTempPath, project.android.signingConfigs.release.keyAlias } println finalApkPath + " zipalign align starting..." exec { executable sdkDir + "/build-tools/26.0.2/zipalign" args "-f", "4", signTempPath, finalApkPath } } } }}/** * 通过过滤黑名单,从而得到白名单列表 * @param resNameArr 资源名<数组> * @param blacklist 黑名单<名字开头> * @return 返回白名单列表 */static Iterable disposeBlacklist(String[] resNameArr, String blacklist) { Iterable arr = new ArrayList<>() StringBuffer sb = new StringBuffer() for (int j = 0; j < resNameArr.length; j++) { for (int i = 0; i < blacklist.length(); i++) { sb.setLength(0) sb.append(blacklist.substring(0, i + 1)) sb.insert(i, "[^") sb.insert(i + 3, "]") arr.add("R." + resNameArr[j] + "." + sb.toString() + "*") } } return arr}/*andResGuard资源混淆*/andResGuard {// mappingFile = file("./resource_mapping.txt") mappingFile = null // 当你使用v2签名的时候,7zip压缩是无法生效的。 use7zip = true useSign = true // 打开这个开关,会keep住所有资源的原始路径,只混淆资源的名字:一般false keepRoot = true //不进行混淆的白名单 String[] resName = [ "anim", "animator", "color", "drawable", "layout", "menu", "mipmap", "string", "style", "item", "dimen", "string-array", "xml", "id", "raw" ] whiteList = disposeBlacklist(resName, "gyq_") //设置压缩的资源 compressFilePattern = [ "*.png", "*.jpg", "*.jpeg", "*.gif", "resources.arsc" ] sevenzip { artifact = 'com.tencent.mm:SevenZip:1.2.8'// path = "D:/7-Zi/7za.exe" } /** * 可选: 如果不设置则会默认覆盖assemble输出的apk **/// finalApkBackupPath = "${project.rootDir}/final.apk" /** * 可选: 指定v1签名时生成jar文件的摘要算法 * 默认值为“SHA1” **/ digestalg = "SHA1"}
project
// Top-level build file where you can add configuration options common to all sub-projects/modules.buildscript { repositories { jcenter() google() } dependencies { classpath 'com.android.tools.build:gradle:3.0.1' classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.8' //mm:AndResGuard // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files }}allprojects { repositories { jcenter() maven { url "http://repo.baichuan-android.taobao.com/content/groups/BaichuanRepositories/" } google() }}task clean(type: Delete) { delete rootProject.buildDir}
更多相关文章
- android 调用第三方软件打开pdf文件
- Android 文件读写的例子
- Android 中常用 MimeType 及对应文件类型
- android连接服务器下载文件工具类
- Android拷贝压缩文件到程序目录
- android中利用socket上传文件
- Android 密度转换 java文件
- android用异步操作AsyncTask编写文件查看器
- Android 打开指定文件夹