From 223f8b185a290bece0a7a50901fa7d88d6f25e0c Mon Sep 17 00:00:00 2001 From: huangx <549631030@qq.com> Date: Wed, 2 Aug 2023 19:16:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=AE=8C=E5=85=A8=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 188 ++++++++++++++++-- app/build.gradle | 3 +- app/proguard-rules.pro | 3 +- .../plugin/junkcode/ext/JunkCodeConfig.groovy | 9 + .../junkcode/task/AndroidJunkCodeTask.groovy | 46 +++-- .../junkcode/task/GenerateJunkCodeTask.groovy | 46 +++-- .../hx/plugin/junkcode/utils/JunkUtil.groovy | 3 + 7 files changed, 245 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index 12245520..c1898ba3 100644 --- a/README.md +++ b/README.md @@ -56,23 +56,6 @@ androidJunkCode { resPrefix = "junk_" drawableCount = 300 stringCount = 300 - - //如果不想用插件默认生成的代码,可通过下面实现自定义。注意,修改生成方式后必须先clean再build才生效 - typeGenerator = { typeBuilder -> - //自定义类实现(类名已经实现随机,Activity类已经实现了onCreate,其它自己实现随机) - //注意设置了此实现将忽略methodGenerator - //TypeSpec.Builder用法请参考(https://github.com/square/javapoet) - } - methodGenerator = { methodBuilder -> - //自定义方法实现(方法名已经实现随机,其它自己实现随机) - //MethodSpec.Builder用法请参考(https://github.com/square/javapoet) - } - layoutGenerator = { stringBuilder -> - //自定义drawable实现(自己实现随机) - } - drawableGenerator = { stringBuilder -> - //自定义layout实现(自己实现随机) - } } variantConfig { //注意:这里的debug,release为变体名称,如果没有设置productFlavors就是buildType名称,如果有设置productFlavors就是flavor+buildType,例如(freeRelease、proRelease) @@ -89,6 +72,177 @@ androidJunkCode { -keep class cn.hx.plugin.ui.** {*;} ``` +**如果不想用插件默认生成的代码,可通过下面实现自定义。注意,修改生成方式后必须先clean再build才生效** + +```groovy +androidJunkCode { + variantConfig { + release { + packageBase = "cn.hx.plugin.ui" + packageCount = 30 + activityCountPerPackage = 30 + excludeActivityJavaFile = false + otherCountPerPackage = 50 + methodCountPerClass = 20 + resPrefix = "junk_" + drawableCount = 300 + stringCount = 300 + + //自定义生成包名(设置此项后packageBase将无效) + //注意,要把生成的包名加入混淆文件 + packageCreator = { tuple2 -> + //int:下标 [0,packageCount) + def index = tuple2.first + //StringBuilder: 生成包名格式xx.xx.xx + def packageNameBuilder = tuple2.second + packageNameBuilder.append("cn.hx.package" + index) + } + + /** + * 自定义生成Activity + */ + activityCreator = { tuple4 -> + //int:下标 [0,activityCountPerPackage) + def index = tuple4.first + //StringBuilder: 生成Activity文件名 + def activityNameBuilder = tuple4.second + //StringBuilder: 生成layout文件名 + def layoutNameBuilder = tuple4.third + //StringBuilder: 生成layout内容 + def layoutContentBuilder = tuple4.fourth + + //例 + activityNameBuilder.append("Activity${index}") + layoutNameBuilder.append("activity_${index}") + layoutContentBuilder.append(''' + + + +''') + } + + //自定义生成类名(Activity除外) + classNameCreator = { tuple2 -> + //int:下标 [0,otherCountPerPackage) + def index = tuple2.first + //StringBuilder: 生成Java文件名 + def classNameBuilder = tuple2.second + + //例 + classNameBuilder.append("Class${index}") + } + + //自定义生成方法名 + methodNameCreator = { tuple2 -> + //int:下标 [0,methodCountPerClass) + def index = tuple2.first + //StringBuilder: 生成的方法名 + def classNameBuilder = tuple2.second + + //例 + classNameBuilder.append("method${index}") + } + + //自定义生成drawable(只支持xml) + drawableCreator = { tuple3 -> + //int:下标 [0,drawableCount) + def index = tuple3.first + //StringBuilder: 生成drawable文件名 + def fileNameBuilder = tuple3.second + //StringBuilder: 生成drawable文件内容 + def contentBuilder = tuple3.third + + //例 + fileNameBuilder.append("drawable${index}") + contentBuilder.append(''' + + + + +''') + } + + //自定义生成 string + stringCreator = { tuple3 -> + //int:下标 [0,drawableCount) + def index = tuple3.first + //StringBuilder: 生成string名 + def keyBuilder = tuple3.second + //StringBuilder: 生成string值 + def valueBuilder = tuple3.third + + //例 + keyBuilder.append("string${index}") + valueBuilder.append("value${index}") + } + + //自定义生成keep.xm + keepCreator = { tuple2 -> + //StringBuilder:生成文件名 + def fileNameBuilder = tuple2.first + //StringBuilder: 生成的文件内容 + def contentBuilder = tuple2.second + + //例 + fileNameBuilder.append("android_junk_code_keep") + contentBuilder.append( "\n") + } + + //自定义类实现(类名已经实现随机,Activity类已经实现了onCreate,其它自己实现随机) + //注意设置了此实现将忽略 methodGenerator,methodCountPerClass + //TypeSpec.Builder用法请参考(https://github.com/square/javapoet) +// typeGenerator = { typeBuilder -> +// //例 +// for (i in 0..<10) { +// typeBuilder.addMethod(MethodSpec.methodBuilder("method" + i) +// .addCode("" + "int total = 0;\n" + "for (int i = 0; i < 10; i++) {\n" + " total += i;\n" + "}\n") +// .build()) +// } +// } + + //自定义方法实现(方法名已经实现随机,其它自己实现随机) + //MethodSpec.Builder用法请参考(https://github.com/square/javapoet) +// methodGenerator = { methodBuilder -> +// //例 +// methodBuilder.addCode("" + "int total = 0;\n" + "for (int i = 0; i < 10; i++) {\n" + " total += i;\n" + "}\n") +// } + } + } +} +``` + +如果所有代码生成都不想用插件来完成,可用如下实现。插件只负责把你生成的文件打进包里 +```groovy +androidJunkCode { + variantConfig { + release { + javaGenerator = { javaDir -> + //File:java目录 + //把你生成的所有java文件放到这个目录下 + } + resGenerator = { resDir -> + //File:res目录 + //把你生成的所有资源文件放到这个目录下 + } + + manifestGenerator = { manifestFile -> + //File:AndroidManifest.xml文件 + //把你生成的AndroidManifest.xml内容写入到这个文件 + } + } + } +} +``` + ### 打包 执行配置变体的打包命令:assembleXXX(XXX是你配置的变体,如:assembleRelease、assembleFreeRelease) diff --git a/app/build.gradle b/app/build.gradle index 0e3b9785..5666d31d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -68,6 +68,7 @@ if (PLUGIN_ENABLE.toBoolean()) { stringCount = 300 //自定义生成包名(设置此项后packageBase将无效) + //注意,要把生成的包名加入混淆文件 packageCreator = { tuple2 -> //int:下标 [0,packageCount) def index = tuple2.first @@ -172,7 +173,7 @@ if (PLUGIN_ENABLE.toBoolean()) { //例 fileNameBuilder.append("android_junk_code_keep") contentBuilder.append( "\n") + " tools:keep=\"@layout/activity_*, @drawable/drawable*\" />\n") } //自定义类实现(类名已经实现随机,Activity类已经实现了onCreate,其它自己实现随机) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index de7893af..5edc9b0e 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -20,4 +20,5 @@ # hide the original source file name. #-renamesourcefileattribute SourceFile --keep class cn.hx.plugin.ui.** {*;} \ No newline at end of file +-keep class cn.hx.plugin.ui.** {*;} +-keep class cn.hx.package*.** {*;} \ No newline at end of file diff --git a/library/src/main/groovy/cn/hx/plugin/junkcode/ext/JunkCodeConfig.groovy b/library/src/main/groovy/cn/hx/plugin/junkcode/ext/JunkCodeConfig.groovy index 871de13b..51b0ef64 100644 --- a/library/src/main/groovy/cn/hx/plugin/junkcode/ext/JunkCodeConfig.groovy +++ b/library/src/main/groovy/cn/hx/plugin/junkcode/ext/JunkCodeConfig.groovy @@ -61,6 +61,15 @@ class JunkCodeConfig { @Internal Action> keepCreator = null + @Internal + Action javaGenerator = null + + @Internal + Action resGenerator = null + + @Internal + Action manifestGenerator = null + @Internal String name = "" diff --git a/library/src/main/groovy/cn/hx/plugin/junkcode/task/AndroidJunkCodeTask.groovy b/library/src/main/groovy/cn/hx/plugin/junkcode/task/AndroidJunkCodeTask.groovy index dcbb93ef..c1410371 100644 --- a/library/src/main/groovy/cn/hx/plugin/junkcode/task/AndroidJunkCodeTask.groovy +++ b/library/src/main/groovy/cn/hx/plugin/junkcode/task/AndroidJunkCodeTask.groovy @@ -31,26 +31,38 @@ abstract class AndroidJunkCodeTask extends DefaultTask { void generateJunkCode() { javaOutDir.deleteDir() resOutDir.deleteDir() - for (int i = 0; i < config.packageCount; i++) { - String packageName - if (config.packageCreator) { - def packageNameBuilder = new StringBuffer() - config.packageCreator.execute(new Tuple2(i, packageNameBuilder)) - packageName = packageNameBuilder.toString() - } else { - if (config.packageBase.isEmpty()) { - packageName = JunkUtil.generateName(i) + if (config.javaGenerator) {//自定义生成java逻辑 + config.javaGenerator.execute(javaOutDir) + } else { + for (int i = 0; i < config.packageCount; i++) { + String packageName + if (config.packageCreator) { + def packageNameBuilder = new StringBuffer() + config.packageCreator.execute(new Tuple2(i, packageNameBuilder)) + packageName = packageNameBuilder.toString() } else { - packageName = config.packageBase + "." + JunkUtil.generateName(i) + if (config.packageBase.isEmpty()) { + packageName = JunkUtil.generateName(i) + } else { + packageName = config.packageBase + "." + JunkUtil.generateName(i) + } } + def list = JunkUtil.generateActivity(javaOutDir, resOutDir, namespace, packageName, config) + activityList.addAll(list) + JunkUtil.generateJava(javaOutDir, packageName, config) } - def list = JunkUtil.generateActivity(javaOutDir, resOutDir, namespace, packageName, config) - activityList.addAll(list) - JunkUtil.generateJava(javaOutDir, packageName, config) } - JunkUtil.generateManifest(manifestOutFile, activityList) - JunkUtil.generateDrawableFiles(resOutDir, config) - JunkUtil.generateStringsFile(resOutDir, config) - JunkUtil.generateKeep(resOutDir, config) + if (config.resGenerator) {//自定义生成res逻辑 + config.resGenerator.execute(resOutDir) + } else { + JunkUtil.generateDrawableFiles(resOutDir, config) + JunkUtil.generateStringsFile(resOutDir, config) + JunkUtil.generateKeep(resOutDir, config) + } + if (config.manifestGenerator) {//自定义生成manifest逻辑 + config.manifestGenerator.execute(manifestOutFile) + } else { + JunkUtil.generateManifest(manifestOutFile, activityList) + } } } \ No newline at end of file diff --git a/library/src/main/groovy/cn/hx/plugin/junkcode/task/GenerateJunkCodeTask.groovy b/library/src/main/groovy/cn/hx/plugin/junkcode/task/GenerateJunkCodeTask.groovy index 81fe04ed..e375440f 100644 --- a/library/src/main/groovy/cn/hx/plugin/junkcode/task/GenerateJunkCodeTask.groovy +++ b/library/src/main/groovy/cn/hx/plugin/junkcode/task/GenerateJunkCodeTask.groovy @@ -33,26 +33,38 @@ abstract class GenerateJunkCodeTask extends DefaultTask { def resDir = getResOutputFolder().get().asFile javaDir.deleteDir() resDir.deleteDir() - for (int i = 0; i < config.packageCount; i++) { - String packageName - if (config.packageCreator) { - def packageNameBuilder = new StringBuffer() - config.packageCreator.execute(new Tuple2(i, packageNameBuilder)) - packageName = packageNameBuilder.toString() - } else { - if (config.packageBase.isEmpty()) { - packageName = JunkUtil.generateName(i) + if (config.javaGenerator) { + config.javaGenerator.execute(javaDir) + } else { + for (int i = 0; i < config.packageCount; i++) { + String packageName + if (config.packageCreator) { + def packageNameBuilder = new StringBuffer() + config.packageCreator.execute(new Tuple2(i, packageNameBuilder)) + packageName = packageNameBuilder.toString() } else { - packageName = config.packageBase + "." + JunkUtil.generateName(i) + if (config.packageBase.isEmpty()) { + packageName = JunkUtil.generateName(i) + } else { + packageName = config.packageBase + "." + JunkUtil.generateName(i) + } } + def list = JunkUtil.generateActivity(javaDir, resDir, namespace, packageName, config) + activityList.addAll(list) + JunkUtil.generateJava(javaDir, packageName, config) } - def list = JunkUtil.generateActivity(javaDir, resDir, namespace, packageName, config) - activityList.addAll(list) - JunkUtil.generateJava(javaDir, packageName, config) } - JunkUtil.generateManifest(getManifestOutputFile().get().asFile, activityList) - JunkUtil.generateDrawableFiles(resDir, config) - JunkUtil.generateStringsFile(resDir, config) - JunkUtil.generateKeep(resDir, config) + if (config.resGenerator) { + config.resGenerator.execute(resOutDir) + } else { + JunkUtil.generateDrawableFiles(resDir, config) + JunkUtil.generateStringsFile(resDir, config) + JunkUtil.generateKeep(resDir, config) + } + if (config.manifestGenerator) { + config.manifestGenerator.execute(getManifestOutputFile().get().asFile) + } else { + JunkUtil.generateManifest(getManifestOutputFile().get().asFile, activityList) + } } } \ No newline at end of file diff --git a/library/src/main/groovy/cn/hx/plugin/junkcode/utils/JunkUtil.groovy b/library/src/main/groovy/cn/hx/plugin/junkcode/utils/JunkUtil.groovy index 845f491c..3f0706d4 100644 --- a/library/src/main/groovy/cn/hx/plugin/junkcode/utils/JunkUtil.groovy +++ b/library/src/main/groovy/cn/hx/plugin/junkcode/utils/JunkUtil.groovy @@ -316,6 +316,9 @@ class JunkUtil { keepName = fileNameBuilder.toString() keepContent = contentBuilder.toString() } else { + if (config.resPrefix.isEmpty()) { + return + } keepName = "android_junk_code_keep" keepContent = "\n"