Skip to content

Commit 2dec460

Browse files
author
BryanSharp
authored
Merge pull request #11 from BryanSharp/independent_task
Independent task
2 parents d69dd55 + 325b66a commit 2dec460

File tree

10 files changed

+296
-131
lines changed

10 files changed

+296
-131
lines changed

build.gradle

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,14 @@ dependencies {
1919
// compile "com.android.tools.build:transform-api:1.5.0"
2020
compile "com.android.tools.build:gradle:2.0.0"
2121
compile "commons-io:commons-io:1.4"
22-
compile 'asm:asm:3.3.1'
2322
}
2423
repositories {
2524
mavenCentral()
2625
}
2726
group = 'com.bryansharp'
28-
version = '1.2.4'
27+
version = '1.2.5'
2928
uploadArchives {
30-
// version = version + '-SNAPSHOT'//if you are testing the demo I provide locally, you can decomment this.
29+
// version = version + '-SNAPSHOT'//if you are testing the demo I provide locally, you can uncomment this.
3130
repositories {
3231
mavenDeployer {
3332
repository(url: uri('./repo'))

src/main/groovy/com/bryansharp/gradle/hibeaver/HiBeaverParams.groovy

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,6 @@ public class HiBeaverParams {
77
boolean keepQuiet = false
88
boolean showHelp = true
99
Map<String, Object> modifyMatchMaps = [:]
10+
Map<String, Map<String, Object>> modifyTasks = [:]
11+
1012
}

src/main/groovy/com/bryansharp/gradle/hibeaver/HiBeaverPluginImpl.groovy

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package com.bryansharp.gradle.hibeaver
33
import com.android.build.gradle.BaseExtension
44
import com.bryansharp.gradle.hibeaver.utils.DataHelper
55
import com.bryansharp.gradle.hibeaver.utils.Log
6+
import com.bryansharp.gradle.hibeaver.utils.ModifyFiles
7+
import com.bryansharp.gradle.hibeaver.utils.Util
68
import org.gradle.api.Plugin
79
import org.gradle.api.Project
810

@@ -11,12 +13,17 @@ class HiBeaverPluginImpl implements Plugin<Project> {
1113
void apply(Project project) {
1214
println ":applied HiBeaver"
1315
project.extensions.create('hiBeaver', HiBeaverParams)
16+
Util.setProject(project)
1417
registerTransform(project)
1518
initDir(project);
1619
project.afterEvaluate {
1720
Log.setQuiet(project.hiBeaver.keepQuiet);
1821
Log.setShowHelp(project.hiBeaver.showHelp);
1922
Log.logHelp();
23+
Map<String, Map<String, Object>> taskMap = project.hiBeaver.modifyTasks;
24+
if (taskMap != null && taskMap.size() > 0) {
25+
generateTasks(project, taskMap);
26+
}
2027
if (project.hiBeaver.watchTimeConsume) {
2128
Log.info "watchTimeConsume enabled"
2229
project.gradle.addListener(new TimeListener())
@@ -29,7 +36,7 @@ class HiBeaverPluginImpl implements Plugin<Project> {
2936
def static registerTransform(Project project) {
3037
// def isApp = project.plugins.hasPlugin("com.android.application")
3138
BaseExtension android = project.extensions.getByType(BaseExtension)
32-
InjectTransform transform = new InjectTransform(project)
39+
InjectTransform transform = new InjectTransform()
3340
android.registerTransform(transform)
3441
}
3542

@@ -38,6 +45,17 @@ class HiBeaverPluginImpl implements Plugin<Project> {
3845
if (!hiBeaverDir.exists()) {
3946
hiBeaverDir.mkdir()
4047
}
48+
File tempDir = new File(hiBeaverDir, "temp")
49+
if (!tempDir.exists()) {
50+
tempDir.mkdir()
51+
}
4152
DataHelper.ext.hiBeaverDir = hiBeaverDir
53+
DataHelper.ext.hiBeaverTempDir = tempDir
54+
}
55+
56+
def static generateTasks(Project project, Map<String, Map<String, Object>> taskMap) {
57+
project.task("hibeaverModifyFiles") << {
58+
ModifyFiles.modify(taskMap)
59+
}
4260
}
4361
}

src/main/groovy/com/bryansharp/gradle/hibeaver/InjectTransform.groovy

Lines changed: 12 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,15 @@ package com.bryansharp.gradle.hibeaver
33
import com.android.annotations.NonNull
44
import com.android.annotations.Nullable
55
import com.android.build.api.transform.*
6-
import com.android.build.gradle.AppExtension
76
import com.android.build.gradle.internal.pipeline.TransformManager
8-
import com.bryansharp.gradle.hibeaver.utils.Const
9-
import com.bryansharp.gradle.hibeaver.utils.DataHelper
10-
import com.bryansharp.gradle.hibeaver.utils.Log
11-
import com.bryansharp.gradle.hibeaver.utils.ModifyClassUtil
12-
import com.bryansharp.gradle.hibeaver.utils.Util
7+
import com.bryansharp.gradle.hibeaver.utils.*
138
import groovy.io.FileType
149
import org.apache.commons.codec.digest.DigestUtils
1510
import org.apache.commons.io.FileUtils
1611
import org.apache.commons.io.IOUtils
17-
import org.gradle.api.Project
1812

1913
import java.util.jar.JarEntry
2014
import java.util.jar.JarFile
21-
import java.util.jar.JarOutputStream
22-
import java.util.zip.ZipEntry
2315

2416
/**
2517
* Created by bryansharp(bsp0911932@163.com) on 2016/5/7.
@@ -30,14 +22,6 @@ import java.util.zip.ZipEntry
3022
*/
3123
public class InjectTransform extends Transform {
3224

33-
static AppExtension android
34-
static Map<String, Integer> targetClasses = [:];
35-
private static Project project;
36-
37-
public InjectTransform(Project project) {
38-
InjectTransform.project = project
39-
}
40-
4125
@Override
4226
String getName() {
4327
return "HiBeaver"
@@ -65,27 +49,11 @@ public class InjectTransform extends Transform {
6549
@NonNull Collection<TransformInput> referencedInputs,
6650
@Nullable TransformOutputProvider outputProvider,
6751
boolean isIncremental) throws IOException, TransformException, InterruptedException {
68-
Log.info "==============hiBeaver ${project.hiBeaver.hiBeaverModifyName + ' '}transform enter=============="
69-
android = project.extensions.getByType(AppExtension)
52+
Log.info "==============hiBeaver ${Util.getHiBeaver().hiBeaverModifyName + ' '}transform enter=============="
7053
// String flavorAndBuildType = context.name.split("For")[1]
7154
// Log.info("flavorAndBuildType ${flavorAndBuildType}")
72-
targetClasses = [:];
73-
Map<String, Object> modifyMatchMaps = project.hiBeaver.modifyMatchMaps;
74-
if (modifyMatchMaps != null) {
75-
def set = modifyMatchMaps.entrySet();
76-
for (Map.Entry<String, Object> entry : set) {
77-
def value = entry.getValue()
78-
if (value) {
79-
int type;
80-
if (value instanceof Map) {
81-
type = Util.typeString2Int(value.get(Const.KEY_CLASSMATCHTYPE));
82-
} else {
83-
type = Util.getMatchTypeByValue(entry.getKey());
84-
}
85-
targetClasses.put(entry.getKey(), type)
86-
}
87-
}
88-
}
55+
Map<String, Object> modifyMatchMaps = Util.getHiBeaver().modifyMatchMaps;
56+
Util.initTargetClasses(modifyMatchMaps)
8957
/**
9058
* 获取所有依赖的classPaths,仅做备用
9159
*/
@@ -106,7 +74,7 @@ public class InjectTransform extends Transform {
10674
}
10775
}
10876

109-
def paths = [android.bootClasspath.get(0).absolutePath/*, injectClassPath*/]
77+
def paths = [Util.getExtension().bootClasspath.get(0).absolutePath/*, injectClassPath*/]
11078
paths.addAll(classPaths)
11179
/**遍历输入文件*/
11280
inputs.each { TransformInput input ->
@@ -180,99 +148,28 @@ public class InjectTransform extends Transform {
180148
FileUtils.copyFile(optJar, checkJarFile);
181149
}
182150

183-
static String shouldModifyClass(String className) {
184-
if (project.hiBeaver.enableModify) {
185-
def set = targetClasses.entrySet();
186-
for (Map.Entry<String, Integer> entry : set) {
187-
def mt = entry.getValue();
188-
String key = entry.getKey()
189-
switch (mt) {
190-
case Const.MT_FULL:
191-
if (className.equals(key)) {
192-
return key;
193-
}
194-
break;
195-
case Const.MT_REGEX:
196-
if (Util.regMatch(key, className)) {
197-
return key;
198-
}
199-
break;
200-
case Const.MT_WILDCARD:
201-
if (Util.wildcardMatchPro(key, className)) {
202-
return key;
203-
}
204-
break;
205-
}
206-
}
207-
return null;
208-
} else {
209-
return null;
210-
}
211-
}
212-
213151
/**
214152
* 植入代码
215153
* @param buildDir 是项目的build class目录,就是我们需要注入的class所在地
216154
* @param lib 这个是hackdex的目录,就是AntilazyLoad类的class文件所在地
217155
*/
218156
public static File modifyJarFile(File jarFile, File tempDir) {
219157
if (jarFile) {
220-
/** 设置输出到的jar */
221-
def hexName = DigestUtils.md5Hex(jarFile.absolutePath).substring(0, 8);
222-
def optJar = new File(tempDir, hexName + jarFile.name)
223-
JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(optJar));
224-
/**
225-
* 读取原jar
226-
*/
227-
def file = new JarFile(jarFile);
228-
Map<String, Object> modifyMatchMaps = project.hiBeaver.modifyMatchMaps
229-
Enumeration enumeration = file.entries();
230-
while (enumeration.hasMoreElements()) {
231-
JarEntry jarEntry = (JarEntry) enumeration.nextElement();
232-
InputStream inputStream = file.getInputStream(jarEntry);
233-
234-
String entryName = jarEntry.getName();
235-
String className
236-
237-
ZipEntry zipEntry = new ZipEntry(entryName);
238-
239-
jarOutputStream.putNextEntry(zipEntry);
158+
Map<String, Object> modifyMatchMaps = Util.getHiBeaver().modifyMatchMaps
159+
return ModifyFiles.modifyJar(jarFile, modifyMatchMaps, tempDir, true)
240160

241-
byte[] modifiedClassBytes = null;
242-
byte[] sourceClassBytes = IOUtils.toByteArray(inputStream);
243-
if (entryName.endsWith(".class")) {
244-
className = path2Classname(entryName)
245-
String key = shouldModifyClass(className)
246-
if (modifyMatchMaps != null && key != null) {
247-
modifiedClassBytes = ModifyClassUtil.modifyClasses(className, sourceClassBytes, modifyMatchMaps.get(key));
248-
}
249-
}
250-
if (modifiedClassBytes == null) {
251-
jarOutputStream.write(sourceClassBytes);
252-
} else {
253-
jarOutputStream.write(modifiedClassBytes);
254-
}
255-
jarOutputStream.closeEntry();
256-
}
257-
// Log.info("${hexName} is modified");
258-
jarOutputStream.close();
259-
file.close();
260-
return optJar;
261161
}
262162
return null;
263163
}
264164

265-
private static String path2Classname(String entryName) {
266-
entryName.replace(File.separator, ".").replace(".class", "")
267-
}
268165

269166
public static File modifyClassFile(File dir, File classFile, File tempDir) {
270167
File modified;
271168
try {
272-
String className = path2Classname(classFile.absolutePath.replace(dir.absolutePath + File.separator, ""));
273-
Map<String, Object> modifyMatchMaps = project.hiBeaver.modifyMatchMaps
169+
String className = Util.path2Classname(classFile.absolutePath.replace(dir.absolutePath + File.separator, ""));
170+
Map<String, Object> modifyMatchMaps = Util.getHiBeaver().modifyMatchMaps
274171
byte[] sourceClassBytes = IOUtils.toByteArray(new FileInputStream(classFile));
275-
String key = shouldModifyClass(className)
172+
String key = Util.shouldModifyClass(className)
276173
if (key != null) {
277174
byte[] modifiedClassBytes = ModifyClassUtil.modifyClasses(className, sourceClassBytes, modifyMatchMaps.get(key));
278175
if (modifiedClassBytes) {
@@ -296,7 +193,7 @@ public class InjectTransform extends Transform {
296193
*/
297194
public static boolean isJarNeedModify(File jarFile) {
298195
boolean modified = false;
299-
if (targetClasses != null && targetClasses.size() > 0) {
196+
if (Util.isTargetClassesNotEmpty()) {
300197
if (jarFile) {
301198
/**
302199
* 读取原jar
@@ -309,7 +206,7 @@ public class InjectTransform extends Transform {
309206
String className
310207
if (entryName.endsWith(".class")) {
311208
className = entryName.replace("/", ".").replace(".class", "")
312-
if (shouldModifyClass(className) != null) {
209+
if (Util.shouldModifyClass(className) != null) {
313210
modified = true;
314211
}
315212
}

src/main/groovy/com/bryansharp/gradle/hibeaver/utils/Const.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ public interface Const {
88
int MT_FULL = 0;
99
int MT_WILDCARD = 1;
1010
int MT_REGEX = 2;
11+
int TY_AAR = 11;
12+
int TY_JAR = 12;
1113
String KEY_CLASSMATCHTYPE="classMatchType";
1214
String KEY_MODIFYMETHODS="modifyMethods";
1315
String KEY_METHODNAME="methodName";

src/main/groovy/com/bryansharp/gradle/hibeaver/utils/MethodLogAdapter.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22

33
import org.objectweb.asm.Attribute;
44
import org.objectweb.asm.Label;
5-
import org.objectweb.asm.MethodAdapter;
65
import org.objectweb.asm.MethodVisitor;
6+
import org.objectweb.asm.Opcodes;
77

88
/**
99
* Created by bryansharp on 17/2/15.
1010
*/
1111

12-
public class MethodLogAdapter extends MethodAdapter {
12+
public class MethodLogAdapter extends MethodVisitor {
1313

1414
public MethodLogAdapter(MethodVisitor mv) {
15-
super(mv);
15+
super(Opcodes.ASM4, mv);
1616
}
1717

1818
/**

src/main/groovy/com/bryansharp/gradle/hibeaver/utils/ModifyClassUtil.groovy

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,29 +45,30 @@ public class ModifyClassUtil {
4545
private
4646
static byte[] modifyClass(byte[] srcClass, List<Map<String, Object>> modifyMatchMaps) throws IOException {
4747
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
48-
ClassAdapter adapter = new MethodFilterClassAdapter(classWriter, modifyMatchMaps);
48+
ClassVisitor adapter = new MethodFilterClassVisitor(classWriter, modifyMatchMaps);
4949
ClassReader cr = new ClassReader(srcClass);
50-
cr.accept(adapter, ClassReader.SKIP_DEBUG);
50+
//cr.accept(visitor, ClassReader.SKIP_DEBUG);
51+
cr.accept(adapter, 0);
5152
return classWriter.toByteArray();
5253
}
5354

5455
private
5556
static void onlyVisitClassMethod(byte[] srcClass, List<Map<String, Object>> modifyMatchMaps) throws IOException {
5657
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
57-
MethodFilterClassAdapter adapter = new MethodFilterClassAdapter(classWriter, modifyMatchMaps);
58-
adapter.onlyVisit = true;
58+
MethodFilterClassVisitor visitor = new MethodFilterClassVisitor(classWriter, modifyMatchMaps);
59+
visitor.onlyVisit = true;
5960
ClassReader cr = new ClassReader(srcClass);
60-
cr.accept(adapter, ClassReader.SKIP_DEBUG);
61+
cr.accept(visitor, 0);
6162
}
6263

63-
static class MethodFilterClassAdapter extends ClassAdapter implements Opcodes {
64+
static class MethodFilterClassVisitor extends ClassVisitor implements Opcodes {
6465
// private String className;
6566
private List<Map<String, Object>> methodMatchMaps;
6667
public boolean onlyVisit = false;
6768

68-
public MethodFilterClassAdapter(
69+
public MethodFilterClassVisitor(
6970
final ClassVisitor cv, List<Map<String, Object>> methodMatchMaps) {
70-
super(cv);
71+
super(Opcodes.ASM4, cv);
7172
// this.className = className;
7273
this.methodMatchMaps = methodMatchMaps;
7374
}

0 commit comments

Comments
 (0)