Skip to content

Commit 9b2b1d7

Browse files
committed
支持自定义混淆文件
1 parent 6eeb3de commit 9b2b1d7

8 files changed

Lines changed: 31 additions & 292 deletions

File tree

README.md

Lines changed: 6 additions & 285 deletions
Original file line numberDiff line numberDiff line change
@@ -2,293 +2,14 @@
22

33
此插件用于做马甲包时,减小马甲包与主包的代码相似度,避免被某些应用市场识别为马甲包。
44

5-
### 使用方法
5+
使用方法见[wiki](https://github.com/qq549631030/AndroidJunkCode/wiki)
66

7-
根目录的build.gradle中:
7+
使用插件[methodCount](https://github.com/KeepSafe/dexcount-gradle-plugin)对比
88

9-
```
10-
buildscript {
11-
repositories {
12-
mavenCentral()
13-
}
14-
dependencies {
15-
classpath "com.github.qq549631030:android-junk-code:x.x.x" //x.x.x换成最新的插件版本号
16-
}
17-
}
18-
```
19-
20-
app目录的build.gradle模块中:
21-
22-
```groovy
23-
apply plugin: 'com.android.application'
24-
apply plugin: 'android-junk-code'
25-
26-
androidJunkCode {
27-
variantConfig {
28-
release {
29-
//注意:这里的release是变体名称,如果没有设置productFlavors就是buildType名称,如果有设置productFlavors就是flavor+buildType,例如(freeRelease、proRelease)
30-
packageBase = "cn.hx.plugin.ui" //生成java类根包名
31-
packageCount = 30 //生成包数量
32-
activityCountPerPackage = 3 //每个包下生成Activity类数量
33-
excludeActivityJavaFile = false
34-
//是否排除生成Activity的Java文件,默认false(layout和写入AndroidManifest.xml还会执行),主要用于处理类似神策全埋点编译过慢问题
35-
otherCountPerPackage = 50 //每个包下生成其它类的数量
36-
methodCountPerClass = 20 //每个类下生成方法数量
37-
resPrefix = "junk_" //生成的layout、drawable、string等资源名前缀
38-
drawableCount = 300 //生成drawable资源数量
39-
stringCount = 300 //生成string数量
40-
}
41-
}
42-
}
43-
```
44-
45-
**注:从1.3.1开始本库已经上传到Gradle Plugin Portal 可直接这样使用**
46-
47-
```groovy
48-
plugins {
49-
//插件id和前面mavenCentral的不一样
50-
//开头是io.github不是com.github
51-
id "io.github.qq549631030.android-junk-code" version "x.x.x"
52-
}
53-
54-
androidJunkCode {
55-
variantConfig {
56-
release {
57-
//...
58-
}
59-
}
60-
}
61-
```
62-
63-
如果有多个变体共用一个配置可以这样做
64-
65-
```groovy
66-
androidJunkCode {
67-
def config = {
68-
packageBase = "cn.hx.plugin.ui"
69-
packageCount = 30
70-
activityCountPerPackage = 3
71-
excludeActivityJavaFile = false
72-
otherCountPerPackage = 50
73-
methodCountPerClass = 20
74-
resPrefix = "junk_"
75-
drawableCount = 300
76-
stringCount = 300
77-
}
78-
variantConfig {
79-
//注意:这里的debug,release为变体名称,如果没有设置productFlavors就是buildType名称,如果有设置productFlavors就是flavor+buildType,例如(freeRelease、proRelease)
80-
debug config
81-
release config
82-
}
83-
}
84-
```
85-
86-
如果APP开启了混淆,需要在混淆文件里配置 (1.3.1之后不需求配置)
87-
88-
```
89-
#cn.hx.plugin.ui为前面配置的packageBase
90-
-keep class cn.hx.plugin.ui.** {*;}
91-
```
92-
93-
**如果不想用插件默认生成的代码,可通过下面实现自定义。注意,修改生成方式后必须先clean再build才生效**
94-
95-
```groovy
96-
androidJunkCode {
97-
variantConfig {
98-
release {
99-
packageBase = "cn.hx.plugin.ui"
100-
packageCount = 30
101-
activityCountPerPackage = 30
102-
excludeActivityJavaFile = false
103-
otherCountPerPackage = 50
104-
methodCountPerClass = 20
105-
resPrefix = "junk_"
106-
drawableCount = 300
107-
stringCount = 300
108-
109-
//自定义生成包名(设置此项后packageBase将无效)
110-
//注意,要把生成的包名加入混淆文件
111-
packageCreator = { tuple2 ->
112-
//int:下标 [0,packageCount)
113-
def index = tuple2.first
114-
//StringBuilder: 生成包名格式xx.xx.xx
115-
def packageNameBuilder = tuple2.second
116-
packageNameBuilder.append("cn.hx.package" + index)
117-
}
118-
119-
/**
120-
* 自定义生成Activity
121-
*/
122-
activityCreator = { tuple4 ->
123-
//int:下标 [0,activityCountPerPackage)
124-
def index = tuple4.first
125-
//StringBuilder: 生成Activity文件名
126-
def activityNameBuilder = tuple4.second
127-
//StringBuilder: 生成layout文件名
128-
def layoutNameBuilder = tuple4.third
129-
//StringBuilder: 生成layout内容
130-
def layoutContentBuilder = tuple4.fourth
131-
132-
//例
133-
activityNameBuilder.append("Activity${index}")
134-
layoutNameBuilder.append("activity_${index}")
135-
layoutContentBuilder.append('''<?xml version="1.0" encoding="utf-8"?>
136-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
137-
android:layout_width="match_parent"
138-
android:layout_height="match_parent"
139-
android:orientation="vertical">
140-
141-
<TextView
142-
android:layout_width="wrap_content"
143-
android:layout_height="wrap_content"
144-
android:layout_gravity="center" />
145-
</LinearLayout>''')
146-
}
147-
148-
//自定义生成类名(Activity除外)
149-
classNameCreator = { tuple2 ->
150-
//int:下标 [0,otherCountPerPackage)
151-
def index = tuple2.first
152-
//StringBuilder: 生成Java文件名
153-
def classNameBuilder = tuple2.second
154-
155-
//例
156-
classNameBuilder.append("Class${index}")
157-
}
158-
159-
//自定义生成方法名
160-
methodNameCreator = { tuple2 ->
161-
//int:下标 [0,methodCountPerClass)
162-
def index = tuple2.first
163-
//StringBuilder: 生成的方法名
164-
def classNameBuilder = tuple2.second
165-
166-
//例
167-
classNameBuilder.append("method${index}")
168-
}
169-
170-
//自定义生成drawable(只支持xml)
171-
drawableCreator = { tuple3 ->
172-
//int:下标 [0,drawableCount)
173-
def index = tuple3.first
174-
//StringBuilder: 生成drawable文件名
175-
def fileNameBuilder = tuple3.second
176-
//StringBuilder: 生成drawable文件内容
177-
def contentBuilder = tuple3.third
178-
179-
//例
180-
fileNameBuilder.append("drawable${index}")
181-
contentBuilder.append('''<?xml version="1.0" encoding="utf-8"?>
182-
<shape xmlns:android="http://schemas.android.com/apk/res/android">
183-
<corners android:radius="4dp" />
184-
<stroke
185-
android:width="1dp"
186-
android:color="#333333" />
187-
</shape>
188-
''')
189-
}
190-
191-
//自定义生成 string
192-
stringCreator = { tuple3 ->
193-
//int:下标 [0,drawableCount)
194-
def index = tuple3.first
195-
//StringBuilder: 生成string名
196-
def keyBuilder = tuple3.second
197-
//StringBuilder: 生成string值
198-
def valueBuilder = tuple3.third
199-
200-
//例
201-
keyBuilder.append("string${index}")
202-
valueBuilder.append("value${index}")
203-
}
204-
205-
//自定义生成keep.xm
206-
keepCreator = { tuple2 ->
207-
//StringBuilder:生成文件名
208-
def fileNameBuilder = tuple2.first
209-
//StringBuilder: 生成的文件内容
210-
def contentBuilder = tuple2.second
211-
212-
//例
213-
fileNameBuilder.append("android_junk_code_keep")
214-
contentBuilder.append( "<resources xmlns:tools=\"http://schemas.android.com/tools\"\n" +
215-
" tools:keep=\"@layout/junk_*, @drawable/junk_*\" />\n")
216-
}
217-
218-
//自定义类实现(类名已经实现随机,Activity类已经实现了onCreate,其它自己实现随机)
219-
//注意设置了此实现将忽略 methodGenerator,methodCountPerClass
220-
//TypeSpec.Builder用法请参考(https://github.com/square/javapoet)
221-
// typeGenerator = { typeBuilder ->
222-
// //例
223-
// for (i in 0..<10) {
224-
// typeBuilder.addMethod(MethodSpec.methodBuilder("method" + i)
225-
// .addCode("" + "int total = 0;\n" + "for (int i = 0; i < 10; i++) {\n" + " total += i;\n" + "}\n")
226-
// .build())
227-
// }
228-
// }
229-
230-
//自定义方法实现(方法名已经实现随机,其它自己实现随机)
231-
//MethodSpec.Builder用法请参考(https://github.com/square/javapoet)
232-
// methodGenerator = { methodBuilder ->
233-
// //例
234-
// methodBuilder.addCode("" + "int total = 0;\n" + "for (int i = 0; i < 10; i++) {\n" + " total += i;\n" + "}\n")
235-
// }
236-
}
237-
}
238-
}
239-
```
240-
241-
如果所有代码生成都不想用插件来完成,可用如下实现。插件只负责把你生成的文件打进包里
242-
243-
```groovy
244-
androidJunkCode {
245-
variantConfig {
246-
release {
247-
javaGenerator = { javaDir ->
248-
//File:java目录
249-
//把你生成的所有java文件放到这个目录下
250-
}
251-
resGenerator = { resDir ->
252-
//File:res目录
253-
//把你生成的所有资源文件放到这个目录下
254-
}
255-
256-
manifestGenerator = { manifestFile ->
257-
//File:AndroidManifest.xml文件
258-
//把你生成的AndroidManifest.xml内容写入到这个文件
259-
}
260-
}
261-
}
262-
}
263-
```
264-
265-
### 打包
266-
267-
执行配置变体的打包命令:assembleXXX(XXX是你配置的变体,如:assembleRelease、assembleFreeRelease)
268-
269-
### 生成文件所在目录
270-
271-
*AGP 7.4.0以前*
272-
build/generated/source/junk
273-
274-
*AGP 7.4.0以后 (XXX是你配置的变体首字母大写,如:Release、FreeRelease)*
275-
build/generated/java/generateXXXJunkCode
276-
build/generated/res/generateXXXJunkCode
277-
build/generated/source/junk/XXX/AndroidManifest.xml
278-
279-
### 使用插件[methodCount](https://github.com/KeepSafe/dexcount-gradle-plugin)对比
280-
281-
#### 未加垃圾代码
282-
283-
**项目代码占比 0.13%**
284-
285-
![方法总数](images/before_total.jpg)![项目方法数](images/before_project.jpg)
286-
287-
#### 加了垃圾代码
288-
289-
**项目代码占比 52.93%**
290-
291-
![方法总数](images/after_total.jpg)![项目方法数](images/after_project.jpg)
9+
| | 方法总数 | 项目方法数 |
10+
| ----------------------------- |:--------------------------------:|:-----------------------------------:|
11+
| 未加垃圾代码<br/><br/>项目代码占比 0.13% | ![方法总数](images/before_total.jpg) | ![项目方法数](images/before_project.jpg) |
12+
| 加了垃圾代码<br/><br/>项目代码占比 52.93% | ![方法总数](images/after_total.jpg) | ![项目方法数](images/after_project.jpg) |
29213

29314
安利我的两个新库:
29415
[PriorityDialog](https://github.com/qq549631030/PriorityDialog)(带优先级对话框实现)

app/build.gradle

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,17 @@ if (PLUGIN_ENABLE.toBoolean()) {
176176
" tools:keep=\"@layout/activity_*, @drawable/drawable*\" />\n")
177177
}
178178

179+
proguardCreator = { tuple2 ->
180+
//List<String>:生成的包名列表
181+
def packageList = tuple2.first
182+
//StringBuilder: 生成的文件内容
183+
def contentBuilder = tuple2.second
184+
185+
//
186+
for (i in 0..<packageList.size()) {
187+
contentBuilder.append("-keep class ${packageList.get(i)}.**{*;}\n")
188+
}
189+
}
179190
//自定义类实现(类名已经实现随机,Activity类已经实现了onCreate,其它自己实现随机)
180191
//注意设置了此实现将忽略 methodGenerator,methodCountPerClass
181192
//TypeSpec.Builder用法请参考(https://github.com/square/javapoet)

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ buildscript {
1111
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
1212
classpath "com.getkeepsafe.dexcount:dexcount-gradle-plugin:3.0.1"
1313
if (PLUGIN_ENABLE.toBoolean()) {
14-
classpath "com.github.qq549631030:android-junk-code:1.3.2"
14+
classpath "com.github.qq549631030:android-junk-code:1.3.3"
1515
}
1616
// NOTE: Do not place your application dependencies here; they belong
1717
// in the individual module build.gradle files

library/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#project
22
GROUP=com.github.qq549631030
33
POM_ARTIFACT_ID=android-junk-code
4-
VERSION_NAME=1.3.2
4+
VERSION_NAME=1.3.3
55
POM_PACKAGING=jar
66

77
POM_NAME=AndroidJunkCode

library/src/main/groovy/cn/hx/plugin/junkcode/ext/JunkCodeConfig.groovy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ class JunkCodeConfig {
6161
@Internal
6262
Action<Tuple2<StringBuilder, StringBuilder>> keepCreator = null
6363

64+
@Internal
65+
Action<Tuple2<List<String>, StringBuilder>> proguardCreator = null
66+
6467
@Internal
6568
Action<File> javaGenerator = null
6669

library/src/main/groovy/cn/hx/plugin/junkcode/task/AndroidJunkCodeTask.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ abstract class AndroidJunkCodeTask extends DefaultTask {
5757
packageList.add(packageName)
5858
}
5959
//生成混淆文件
60-
JunkUtil.generateProguard(proguardOutFile, packageList)
60+
JunkUtil.generateProguard(proguardOutFile, packageList, config)
6161
}
6262
if (config.resGenerator) {//自定义生成res逻辑
6363
config.resGenerator.execute(resOutDir)

library/src/main/groovy/cn/hx/plugin/junkcode/task/GenerateJunkCodeTask.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ abstract class GenerateJunkCodeTask extends DefaultTask {
7070
packageList.add(packageName)
7171
}
7272
//生成混淆文件
73-
JunkUtil.generateProguard(getProguardOutputFile().get().asFile, packageList)
73+
JunkUtil.generateProguard(getProguardOutputFile().get().asFile, packageList, config)
7474
}
7575
if (config.resGenerator) {
7676
config.resGenerator.execute(resOutDir)

library/src/main/groovy/cn/hx/plugin/junkcode/utils/JunkUtil.groovy

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -352,10 +352,14 @@ class JunkUtil {
352352
* @param manifestFile
353353
* @param activityList
354354
*/
355-
static void generateProguard(File proguardFile, List<String> packageList) {
355+
static void generateProguard(File proguardFile, List<String> packageList, JunkCodeConfig config) {
356356
StringBuilder sb = new StringBuilder()
357-
for (i in 0..<packageList.size()) {
358-
sb.append("-keep class ${packageList.get(i)}.**{*;}\n")
357+
if (config.proguardCreator) {
358+
config.proguardCreator.execute(new Tuple2(packageList, sb))
359+
} else {
360+
for (i in 0..<packageList.size()) {
361+
sb.append("-keep class ${packageList.get(i)}.**{*;}\n")
362+
}
359363
}
360364
writeStringToFile(proguardFile, sb.toString())
361365
}

0 commit comments

Comments
 (0)