Skip to content

Commit

Permalink
1.0.1 release,优化配置方式
Browse files Browse the repository at this point in the history
  • Loading branch information
huangx committed Jun 17, 2020
1 parent 934755c commit 5c6e40e
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 93 deletions.
29 changes: 19 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Android垃圾代码生成插件

[![Download](https://api.bintray.com/packages/qq549631030/maven/AndroidJunkCode/images/download.svg) ](https://bintray.com/qq549631030/maven/AndroidJunkCode/_latestVersion)

此插件用于做马甲包时,减小马甲包与主包的代码相似度,避免被OPPO、VIVO等应用市场识别为马甲包。

### 使用方法
Expand All @@ -8,7 +10,7 @@
```
buildscript {
dependencies {
classpath "cn.hx.plugin:android-junk-code:1.0.0"
classpath "cn.hx.plugin:android-junk-code:1.0.1"
}
}
```
Expand All @@ -21,14 +23,21 @@ android {
//xxx
}
androidJunkCode {
variants = ["debug"] //要生成垃圾代码的variant列表 eg:["vivoRelease","oppoRelease"]
packages = ["cn.hx.test"] //要在哪些包名下生成Java类 eg:["cn.hx.test","cn.hx.demo"]
activityCountPerPackage = 2 //每个包下生成Activity数量
otherCountPerPackage = 10 //每个包下生成普通类数量
methodCountPerClass = 10 每个类生生成方法数量
resPrefix = "hx_junk_" 生成的layout、drawable、string等资源名前缀
drawableCount = 30 生成drawable资源数量
stringCount = 30 生成string数量
android.applicationVariants.all { variant ->
switch (variant.name) {
case "debug":
case "release":
androidJunkCode.configMap.put(variant.name, {
packageBase = "cn.hx.plugin.ui" //生成java类根包名
packageCount = 30 //生成包数量
activityCountPerPackage = 3 //每个包下生成Activity数量
otherCountPerPackage = 10 //每个类生生成方法数量
methodCountPerClass = 10 //每个类生生成方法数量
resPrefix = "lite_junk_" //生成的layout、drawable、string等资源名前缀
drawableCount = 30 //生成drawable资源数量
stringCount = 30 //生成string数量
})
break
}
}
```
29 changes: 19 additions & 10 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,24 @@ android {
}
}

android.applicationVariants.all { variant ->
switch (variant.name) {
case "debug":
case "release":
androidJunkCode.configMap.put(variant.name, {
packageBase = "cn.hx.plugin.ui"
packageCount = 30
activityCountPerPackage = 3
otherCountPerPackage = 10
methodCountPerClass = 10
resPrefix = "lite_junk_"
drawableCount = 30
stringCount = 30
})
break
}
}

dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
Expand All @@ -36,16 +54,7 @@ dependencies {

}

androidJunkCode {
variants = ["debug"]
packages = ["cn.hx.test"]
activityCountPerPackage = 2
otherCountPerPackage = 10
methodCountPerClass = 10
resPrefix = "hx_junk_"
drawableCount = 30
stringCount = 30
}

//
//afterEvaluate {
// project.tasks.all { task ->
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ buildscript {
classpath "com.android.tools.build:gradle:4.0.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.novoda:bintray-release:0.9.2'
classpath "cn.hx.plugin:android-junk-code:1.0.0"
classpath "cn.hx.plugin:android-junk-code:1.0.1"

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand Down
2 changes: 1 addition & 1 deletion library/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ uploadArchives {
// authentication(userName: mavenUserName, password: mavenUserPassword)
// }
repository(url: uri("../repo"))
pom.version = '1.0.0'
pom.version = '1.0.1'
pom.artifactId = 'android-junk-code'
pom.groupId = 'cn.hx.plugin'
pom.project {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
package cn.hx.plugin.junkcode.ext

class AndroidJunkCodeExt {
String[] variants = []
String[] packages = []
int activityCountPerPackage = 0
int otherCountPerPackage = 0
int methodCountPerClass = 0
String resPrefix = "junk_"
int drawableCount = 0
int stringCount = 0
Map<String, Closure<JunkCodeConfig>> configMap = [:]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package cn.hx.plugin.junkcode.ext

import org.gradle.api.tasks.Input

class JunkCodeConfig {
@Input
String packageBase = ""
@Input
int packageCount = 0
@Input
int activityCountPerPackage = 0
@Input
int otherCountPerPackage = 0
@Input
int methodCountPerClass = 0
@Input
String resPrefix = "junk_"
@Input
int drawableCount = 0
@Input
int stringCount = 0
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cn.hx.plugin.junkcode.plugin

import cn.hx.plugin.junkcode.ext.AndroidJunkCodeExt
import cn.hx.plugin.junkcode.ext.JunkCodeConfig
import cn.hx.plugin.junkcode.task.AndroidJunkCodeTask
import com.android.build.gradle.AppExtension
import com.android.build.gradle.api.ApplicationVariant
Expand All @@ -16,32 +17,33 @@ class AndroidJunkCodePlugin implements Plugin<Project> {
throw IllegalArgumentException("must apply this plugin after 'com.android.application'")
}
def generateJunkCodeExt = project.extensions.create("androidJunkCode", AndroidJunkCodeExt)
android.applicationVariants.all { variant ->
def variantName = variant.name
if (variantName in generateJunkCodeExt.variants) {
def dir = new File(project.buildDir, "generated/source/junk/$variantName")
String packageName = findPackageName(variant)
def generateJunkCodeTask = project.task("generateJunkCode${variantName.capitalize()}", type: AndroidJunkCodeTask) {
manifestPackageName = packageName
packages = generateJunkCodeExt.packages
activityCountPerPackage = generateJunkCodeExt.activityCountPerPackage
otherCountPerPackage = generateJunkCodeExt.otherCountPerPackage
methodCountPerClass = generateJunkCodeExt.methodCountPerClass
resPrefix = generateJunkCodeExt.resPrefix
drawableCount = generateJunkCodeExt.drawableCount
stringCount = generateJunkCodeExt.stringCount
outDir = dir
}
//将自动生成的AndroidManifest.xml加入到一个未被占用的manifest位置(如果都占用了就不合并了,通常较少出现全被占用情况)
for (int i = 0; i < variant.sourceSets.size(); i++) {
def sourceSet = variant.sourceSets[i]
if (!sourceSet.manifestFile.exists()) {
android.sourceSets."${sourceSet.name}".manifest.srcFile(new File(dir, "AndroidManifest.xml").absolutePath)
break
project.afterEvaluate {
android.applicationVariants.all { variant ->
def variantName = variant.name
Closure<JunkCodeConfig> junkCodeConfig = generateJunkCodeExt.configMap[variantName]
if (junkCodeConfig) {
def dir = new File(project.buildDir, "generated/source/junk/$variantName")
String packageName = findPackageName(variant)
def generateJunkCodeTask = project.task("generateJunkCode${variantName.capitalize()}", type: AndroidJunkCodeTask) {
junkCodeConfig.delegate = config
junkCodeConfig.resolveStrategy = DELEGATE_FIRST
junkCodeConfig.call()
manifestPackageName = packageName
outDir = dir
}
//将自动生成的AndroidManifest.xml加入到一个未被占用的manifest位置(如果都占用了就不合并了,通常较少出现全被占用情况)
for (int i = variant.sourceSets.size() - 1; i >= 0; i--) {
def sourceSet = variant.sourceSets[i]
if (!sourceSet.manifestFile.exists()) {
android.sourceSets."${sourceSet.name}".manifest.srcFile(new File(dir, "AndroidManifest.xml").absolutePath)
break
}
}
android.sourceSets."${variantName}".res.srcDir(new File(dir, "res"))
variant.registerJavaGeneratingTask(generateJunkCodeTask, new File(dir, "java"))
//在执行generateBuildConfig之前执行generateJunkCodeTask
variant.generateBuildConfigProvider.get().dependsOn(generateJunkCodeTask)
}
android.sourceSets."main".res.srcDir(new File(dir, "res"))
variant.registerJavaGeneratingTask(generateJunkCodeTask, dir)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package cn.hx.plugin.junkcode.task


import cn.hx.plugin.junkcode.template.ResTemplate
import cn.hx.plugin.junkcode.ext.JunkCodeConfig
import cn.hx.plugin.junkcode.template.ManifestTemplate
import cn.hx.plugin.junkcode.template.ResTemplate
import com.squareup.javapoet.ClassName
import com.squareup.javapoet.JavaFile
import com.squareup.javapoet.MethodSpec
import com.squareup.javapoet.TypeSpec
import groovy.text.GStringTemplateEngine
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Nested
import org.gradle.api.tasks.OutputDirectories
import org.gradle.api.tasks.TaskAction

Expand All @@ -21,28 +22,20 @@ class AndroidJunkCodeTask extends DefaultTask {

static abc = "abcdefghijklmnopqrstuvwxyz".toCharArray()

@Nested
JunkCodeConfig config = new JunkCodeConfig()

@Input
String manifestPackageName = ""
@Input
String[] packages = []
@Input
int activityCountPerPackage = 0
@Input
int otherCountPerPackage = 0
@Input
int methodCountPerClass = 0
@Input
String resPrefix = "junk_"
@Input
int drawableCount = 0
@Input
int stringCount = 0

@OutputDirectories
File outDir

@TaskAction
void execute() {
if (outDir.exists()) {
outDir.deleteDir()
}
//通过成类
generateClasses()
//生成资源
Expand All @@ -53,28 +46,26 @@ class AndroidJunkCodeTask extends DefaultTask {
* 生成java代码和AndroidManifest.xml
*/
void generateClasses() {
def manifestFile = new File(outDir, "AndroidManifest.xml")
if (manifestFile.exists()) {
manifestFile.delete()
}
packages.each { packageName ->
def javaDir = new File(outDir, "java")
for (int i = 0; i < config.packageCount; i++) {
String packageName = config.packageBase + "." + generateName(i)
//生成Activity
for (int i = 0; i < activityCountPerPackage; i++) {
def activityPreName = generateName(i)
for (int j = 0; j < config.activityCountPerPackage; j++) {
def activityPreName = generateName(j)
generateActivity(packageName, activityPreName)
}
//生成其它类
for (int i = 0; i < otherCountPerPackage; i++) {
def className = generateName(i).capitalize()
for (int j = 0; j < config.otherCountPerPackage; j++) {
def className = generateName(j).capitalize()
def typeBuilder = TypeSpec.classBuilder(className)
for (int j = 0; j < methodCountPerClass; j++) {
def methodName = generateName(j)
for (int k = 0; k < config.methodCountPerClass; k++) {
def methodName = generateName(k)
def methodBuilder = MethodSpec.methodBuilder(methodName)
generateMethods(methodBuilder)
typeBuilder.addMethod(methodBuilder.build())
}
def fileBuilder = JavaFile.builder(packageName, typeBuilder.build())
fileBuilder.build().writeTo(outDir)
fileBuilder.build().writeTo(javaDir)
}
}
}
Expand Down Expand Up @@ -133,8 +124,9 @@ class AndroidJunkCodeTask extends DefaultTask {
* @param activityPreName
*/
void generateActivity(String packageName, String activityPreName) {
def javaDir = new File(outDir, "java")
def className = activityPreName.capitalize() + "Activity"
def layoutName = "${resPrefix.toLowerCase()}${packageName.replace(".", "_")}_activity_${activityPreName}"
def layoutName = "${config.resPrefix.toLowerCase()}${packageName.replace(".", "_")}_activity_${activityPreName}"
generateLayout(layoutName)
def typeBuilder = TypeSpec.classBuilder(className)
typeBuilder.superclass(ClassName.get("android.app", "Activity"))
Expand All @@ -148,14 +140,14 @@ class AndroidJunkCodeTask extends DefaultTask {
.addStatement("setContentView(\$T.layout.${layoutName})", ClassName.get(manifestPackageName, "R"))
.build())
//其它方法
for (int j = 0; j < methodCountPerClass; j++) {
for (int j = 0; j < config.methodCountPerClass; j++) {
def methodName = generateName(j)
def methodBuilder = MethodSpec.methodBuilder(methodName)
generateMethods(methodBuilder)
typeBuilder.addMethod(methodBuilder.build())
}
def fileBuilder = JavaFile.builder(packageName, typeBuilder.build())
fileBuilder.build().writeTo(outDir)
fileBuilder.build().writeTo(javaDir)
addToManifestByFileIo(className, packageName)
}

Expand All @@ -164,17 +156,13 @@ class AndroidJunkCodeTask extends DefaultTask {
*/
void generateRes() {
//生成drawable
for (int i = 0; i < drawableCount; i++) {
def drawableName = "${resPrefix.toLowerCase()}${generateName(i)}"
for (int i = 0; i < config.drawableCount; i++) {
def drawableName = "${config.resPrefix.toLowerCase()}${generateName(i)}"
generateDrawable(drawableName)
}
//生成string
def stringFile = new File(outDir, "res/values/strings.xml")
if (stringFile.exists()) {
stringFile.delete()
}
for (int i = 0; i < stringCount; i++) {
def name = "${resPrefix.toLowerCase()}${generateName(i)}"
for (int i = 0; i < config.stringCount; i++) {
def name = "${config.resPrefix.toLowerCase()}${generateName(i)}"
def value = name
addStringByFileIo(name, value)
}
Expand Down Expand Up @@ -242,6 +230,9 @@ class AndroidJunkCodeTask extends DefaultTask {
*/
void addToManifestByFileIo(String activityName, String packageName) {
def manifestFile = new File(outDir, "AndroidManifest.xml")
if (!manifestFile.getParentFile().exists()) {
manifestFile.getParentFile().mkdirs()
}
if (!manifestFile.exists()) {
def template = ManifestTemplate.TEMPLATE
FileWriter writer
Expand Down

0 comments on commit 5c6e40e

Please sign in to comment.