From cce6904c8a1125461490baafe1f2dcc96fa2b409 Mon Sep 17 00:00:00 2001 From: keyongyu Date: Tue, 15 Aug 2017 11:37:27 +0800 Subject: [PATCH 01/10] =?UTF-8?q?libs=E7=9A=84jar=E9=87=8D=E5=AE=9A?= =?UTF-8?q?=E5=90=91=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../replugin/gradle/plugin/inner/Util.groovy | 131 ++++++++++++++++-- 1 file changed, 117 insertions(+), 14 deletions(-) diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy index ce7d506b..d0637cc6 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy @@ -22,13 +22,17 @@ import com.android.build.api.transform.JarInput import com.android.build.api.transform.TransformInput import com.android.build.gradle.internal.scope.GlobalScope import com.android.sdklib.IAndroidTarget +import com.qihoo360.replugin.gradle.plugin.AppConstant +import org.apache.commons.codec.digest.DigestUtils import org.apache.commons.io.FileUtils import com.google.common.base.Charsets import com.google.common.hash.Hashing import org.gradle.api.Project +import java.lang.reflect.Field import java.nio.file.Files import java.nio.file.Paths +import java.util.zip.ZipEntry import java.util.zip.ZipFile import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES; @@ -95,26 +99,125 @@ public class Util { } } else { + //重定向jar + File reJar = new File(project.getBuildDir().path + + File.separator + FD_INTERMEDIATES + File.separator + "replugin-jar" + + File.separator + md5File(jar) + ".jar"); + String reJarPath = reJar.getAbsolutePath() + boolean needInject = false + if (reJar.exists()) { + //检查修改插件版本 + needInject = checkJarInjectorVersion(reJarPath) + } else { + FileUtils.copyFile(jar, reJar) + needInject = true; + } + //设置重定向jar + setJarInput(jarInput, reJar) + if(needInject){ + includeJars << reJarPath + map.put(reJarPath, reJarPath) + + /* 将 jar 包解压,并将解压后的目录加入 classpath */ + // println ">>> 解压Jar${jarPath}" + String jarZipDir = reJar.getParent() + File.separatorChar + reJar.getName().replace('.jar', '') + if (unzip(jarPath, jarZipDir)) { + classPath << jarZipDir + //保存修改的插件版本号 + saveJarInjectorVersion(jarZipDir) + visitor.setBaseDir(jarZipDir) + Files.walkFileTree(Paths.get(jarZipDir), visitor) + } + // 删除 jar + FileUtils.forceDelete(reJar) + } + } + } + } + return classPath + } - includeJars << jarPath - map.put(jarPath, jarPath) + def static md5File(File jar){ + FileInputStream fileInputStream = new FileInputStream(jar); + String md5 = DigestUtils.md5Hex(fileInputStream); + fileInputStream.close() + return md5 + } - /* 将 jar 包解压,并将解压后的目录加入 classpath */ - // println ">>> 解压Jar${jarPath}" - String jarZipDir = jar.getParent() + File.separatorChar + jar.getName().replace('.jar', '') - if (unzip(jarPath, jarZipDir)) { - classPath << jarZipDir + def static setJarInput(JarInput jarInput, File rejar) { + Field fileField = null; + Class clazz = jarInput.getClass(); + while(fileField == null && clazz != Object.class){ + try { + fileField = clazz.getDeclaredField("file"); + } catch (Exception e) { + //ignore + clazz = clazz.getSuperclass(); + } + } + if(fileField != null){ + fileField.setAccessible(true); + fileField.set(jarInput, rejar); + } + } - visitor.setBaseDir(jarZipDir) - Files.walkFileTree(Paths.get(jarZipDir), visitor) - } + /** + * 通过META-INF/replugin_version.txt判断是否需要修改 + */ + def static checkJarInjectorVersion(String jar) { + boolean needInjector = true; + ZipFile zf = null; + ZipEntry ze = null; + InputStream inputStream = null; + try{ + zf = new ZipFile(jar); + ze = zf.getEntry("META-INF/replugin_version.txt"); + if(ze != null){ + byte[] data = new byte[jar.length()]; + inputStream = zf.getInputStream(ze); + int len = inputStream.read(data, 0, data.length); + String ver = new String(data, "utf-8").trim(); + needInjector = !AppConstant.VER.equals(ver); + } + }catch (Throwable e){ + // + }finally{ + if(inputStream != null){ + inputStream.close(); + } + if(zf != null){ + zf.close(); + } + } + return needInjector; + } - // 删除 jar - FileUtils.forceDelete(jar) - } + /** + * 记录版本号到META-INF/replugin_version.txt + */ + def static saveJarInjectorVersion(String jarZipDir) { + File verFile = new File(jarZipDir, "META-INF/replugin_version.txt"); + if(verFile.exists()){ + verFile.delete(); + }else{ + File dir = verFile.getParentFile(); + if(!dir.exists()){ + dir.mkdirs(); + } + } + verFile.createNewFile(); + FileOutputStream fileOutputStream = null; + try{ + fileOutputStream = new FileOutputStream(verFile); + fileOutputStream.write(AppConstant.VER.getBytes("utf-8")); + fileOutputStream.flush(); + }catch (Throwable e){ + // + }finally{ + if(fileOutputStream!=null){ + fileOutputStream.close(); } } - return classPath } /** From 58e5a0d3fa9974d2818d20fe886d6650fa06835d Mon Sep 17 00:00:00 2001 From: keyongyu Date: Tue, 15 Aug 2017 14:16:33 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E6=94=B9=E4=B8=BAjson=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/inner/InjectorVersion.groovy | 32 +++ .../replugin/gradle/plugin/inner/Util.groovy | 205 ++++++++++-------- 2 files changed, 147 insertions(+), 90 deletions(-) create mode 100644 replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/InjectorVersion.groovy diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/InjectorVersion.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/InjectorVersion.groovy new file mode 100644 index 00000000..5fdbb46b --- /dev/null +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/InjectorVersion.groovy @@ -0,0 +1,32 @@ + +package com.qihoo360.replugin.gradle.plugin.inner + +import com.qihoo360.replugin.gradle.plugin.AppConstant + +/** + * @author 247321453 + */ +public class InjectorVersion { + + def String jarPath + + def String jarMd5 + + def String pluginVersion + + InjectorVersion(){ + + } + + InjectorVersion(String jarPath, String jarMd5, String pluginVersion) { + this.jarPath = jarPath + this.jarMd5 = jarMd5 + this.pluginVersion = pluginVersion + } + + InjectorVersion(File jar){ + this.jarPath = jar.getAbsolutePath() + this.jarMd5 = Util.md5File(jar) + this.pluginVersion = AppConstant.VER + } +} diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy index d0637cc6..f4e38fbe 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy @@ -22,6 +22,10 @@ import com.android.build.api.transform.JarInput import com.android.build.api.transform.TransformInput import com.android.build.gradle.internal.scope.GlobalScope import com.android.sdklib.IAndroidTarget +import com.google.common.reflect.TypeToken +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import com.google.gson.stream.JsonReader import com.qihoo360.replugin.gradle.plugin.AppConstant import org.apache.commons.codec.digest.DigestUtils import org.apache.commons.io.FileUtils @@ -32,7 +36,6 @@ import org.gradle.api.Project import java.lang.reflect.Field import java.nio.file.Files import java.nio.file.Paths -import java.util.zip.ZipEntry import java.util.zip.ZipFile import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES; @@ -69,7 +72,8 @@ public class Util { def projectDir = project.getRootDir().absolutePath println ">>> Unzip Jar ..." - + Map injectorMap = readJarInjectorHistory(project) + boolean needSave = false inputs.each { TransformInput input -> input.directoryInputs.each { DirectoryInput dirInput -> @@ -100,123 +104,144 @@ public class Util { } else { //重定向jar - File reJar = new File(project.getBuildDir().path + - File.separator + FD_INTERMEDIATES + File.separator + "replugin-jar" - + File.separator + md5File(jar) + ".jar"); - String reJarPath = reJar.getAbsolutePath() - boolean needInject = false - if (reJar.exists()) { - //检查修改插件版本 - needInject = checkJarInjectorVersion(reJarPath) + if (jarPath.contains(File.separator + FD_INTERMEDIATES + File.separator + "replugin-jar")) { + // } else { - FileUtils.copyFile(jar, reJar) - needInject = true; - } - //设置重定向jar - setJarInput(jarInput, reJar) - if(needInject){ - includeJars << reJarPath - map.put(reJarPath, reJarPath) - - /* 将 jar 包解压,并将解压后的目录加入 classpath */ - // println ">>> 解压Jar${jarPath}" - String jarZipDir = reJar.getParent() + File.separatorChar + reJar.getName().replace('.jar', '') - if (unzip(jarPath, jarZipDir)) { - classPath << jarZipDir - //保存修改的插件版本号 - saveJarInjectorVersion(jarZipDir) - visitor.setBaseDir(jarZipDir) - Files.walkFileTree(Paths.get(jarZipDir), visitor) + String md5 = md5File(jar); + File reJar = new File(project.getBuildDir().path + + File.separator + FD_INTERMEDIATES + File.separator + "replugin-jar" + + File.separator + md5 + ".jar"); + String reJarPath = reJar.getAbsolutePath() + + boolean needInject = false + if (reJar.exists()) { + //检查修改插件版本 + InjectorVersion injectorVersion = injectorMap.get(jar.getAbsolutePath()); + if (injectorVersion != null) { + if (!AppConstant.VER.equals(injectorVersion.pluginVersion)) { + //版本变化了 + needInject = true + } else { + if (!md5.equals(injectorVersion.jarMd5)) { + //原始jar内容变化 + needInject = true + } + } + } else { + //无记录 + needInject = true + } + } else { + FileUtils.copyFile(jar, reJar) + needInject = true; + } + //设置重定向jar + setJarInput(jarInput, reJar) + if (needInject) { + includeJars << reJarPath + map.put(reJarPath, reJarPath) + + /* 将 jar 包解压,并将解压后的目录加入 classpath */ + // println ">>> 解压Jar${jarPath}" + String jarZipDir = reJar.getParent() + File.separatorChar + reJar.getName().replace('.jar', '') + if (unzip(jarPath, jarZipDir)) { + classPath << jarZipDir + //保存修改的插件版本号 + needSave = true + injectorMap.put(jar.getAbsolutePath(), new InjectorVersion(jar)) + + visitor.setBaseDir(jarZipDir) + Files.walkFileTree(Paths.get(jarZipDir), visitor) + } + // 删除 jar + FileUtils.forceDelete(reJar) + } else { + map.remove(reJarPath) + includeJars.remove(reJarPath) } - // 删除 jar - FileUtils.forceDelete(reJar) } } } } + if (needSave) { + saveJarInjectorHistory(project, injectorMap) + } return classPath } - def static md5File(File jar){ + /** + * 计算jar的md5 + */ + def static md5File(File jar) { FileInputStream fileInputStream = new FileInputStream(jar); String md5 = DigestUtils.md5Hex(fileInputStream); fileInputStream.close() return md5 } - def static setJarInput(JarInput jarInput, File rejar) { - Field fileField = null; - Class clazz = jarInput.getClass(); - while(fileField == null && clazz != Object.class){ - try { - fileField = clazz.getDeclaredField("file"); - } catch (Exception e) { - //ignore - clazz = clazz.getSuperclass(); - } + /** + * 读取修改jar的记录 + */ + def static readJarInjectorHistory(Project project) { + File file = new File(project.getBuildDir(), FD_INTERMEDIATES + + File.separator + "replugin-jar" + File.separator + "version.json"); + if (!file.exists()) { + return new HashMap(); } - if(fileField != null){ - fileField.setAccessible(true); - fileField.set(jarInput, rejar); + Gson gson = new GsonBuilder() + .create(); + FileReader fileReader = new FileReader(file) + JsonReader jsonReader = new JsonReader(fileReader); + Map injectorMap = gson.fromJson(jsonReader, new TypeToken>() { + }.getType()); + jsonReader.close() + if (injectorMap == null) { + injectorMap = new HashMap(); } + return injectorMap; } /** - * 通过META-INF/replugin_version.txt判断是否需要修改 + * 保存修改jar的记录 */ - def static checkJarInjectorVersion(String jar) { - boolean needInjector = true; - ZipFile zf = null; - ZipEntry ze = null; - InputStream inputStream = null; - try{ - zf = new ZipFile(jar); - ze = zf.getEntry("META-INF/replugin_version.txt"); - if(ze != null){ - byte[] data = new byte[jar.length()]; - inputStream = zf.getInputStream(ze); - int len = inputStream.read(data, 0, data.length); - String ver = new String(data, "utf-8").trim(); - needInjector = !AppConstant.VER.equals(ver); - } - }catch (Throwable e){ - // - }finally{ - if(inputStream != null){ - inputStream.close(); - } - if(zf != null){ - zf.close(); + def static saveJarInjectorHistory(Project project, Map injectorMap) { + Gson gson = new GsonBuilder() + .setPrettyPrinting() + .create(); + File file = new File(project.getBuildDir(), FD_INTERMEDIATES + + File.separator + "replugin-jar" + File.separator + "version.json"); + if (file.exists()) { + file.delete() + } else { + File dir = file.getParentFile(); + if (!dir.exists()) { + dir.mkdirs() } } - return needInjector; + file.createNewFile() + FileWriter fileWriter = new FileWriter(file); + String json = gson.toJson(injectorMap); + fileWriter.write(json) + fileWriter.close() } /** - * 记录版本号到META-INF/replugin_version.txt + * 反射,修改引用的jar路径 */ - def static saveJarInjectorVersion(String jarZipDir) { - File verFile = new File(jarZipDir, "META-INF/replugin_version.txt"); - if(verFile.exists()){ - verFile.delete(); - }else{ - File dir = verFile.getParentFile(); - if(!dir.exists()){ - dir.mkdirs(); + def static setJarInput(JarInput jarInput, File rejar) { + Field fileField = null; + Class clazz = jarInput.getClass(); + while (fileField == null && clazz != Object.class) { + try { + fileField = clazz.getDeclaredField("file"); + } catch (Exception e) { + //ignore + clazz = clazz.getSuperclass(); } } - verFile.createNewFile(); - FileOutputStream fileOutputStream = null; - try{ - fileOutputStream = new FileOutputStream(verFile); - fileOutputStream.write(AppConstant.VER.getBytes("utf-8")); - fileOutputStream.flush(); - }catch (Throwable e){ - // - }finally{ - if(fileOutputStream!=null){ - fileOutputStream.close(); - } + if (fileField != null) { + fileField.setAccessible(true); + fileField.set(jarInput, rejar); } } From 82142dd6aa59c94aae2202ea830f00ea0513b0c6 Mon Sep 17 00:00:00 2001 From: keyongyu Date: Tue, 15 Aug 2017 14:27:51 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E4=B8=8D=E9=9C=80=E8=A6=81=E4=BF=9D?= =?UTF-8?q?=E5=AD=98jar=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../replugin/gradle/plugin/inner/InjectorVersion.groovy | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/InjectorVersion.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/InjectorVersion.groovy index 5fdbb46b..476109b3 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/InjectorVersion.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/InjectorVersion.groovy @@ -8,8 +8,6 @@ import com.qihoo360.replugin.gradle.plugin.AppConstant */ public class InjectorVersion { - def String jarPath - def String jarMd5 def String pluginVersion @@ -18,14 +16,12 @@ public class InjectorVersion { } - InjectorVersion(String jarPath, String jarMd5, String pluginVersion) { - this.jarPath = jarPath + InjectorVersion(String jarMd5, String pluginVersion) { this.jarMd5 = jarMd5 this.pluginVersion = pluginVersion } InjectorVersion(File jar){ - this.jarPath = jar.getAbsolutePath() this.jarMd5 = Util.md5File(jar) this.pluginVersion = AppConstant.VER } From e27e49dd639e5426be7464f2ea3dd61a8f78158a Mon Sep 17 00:00:00 2001 From: keyongyu Date: Mon, 21 Aug 2017 15:01:33 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E5=88=86buildType?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ctorVersion.groovy => JarPatchInfo.groovy} | 8 +- .../plugin/inner/ReClassTransform.groovy | 10 +- .../replugin/gradle/plugin/inner/Util.groovy | 134 +++++++++--------- 3 files changed, 75 insertions(+), 77 deletions(-) rename replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/{InjectorVersion.groovy => JarPatchInfo.groovy} (72%) diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/InjectorVersion.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/JarPatchInfo.groovy similarity index 72% rename from replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/InjectorVersion.groovy rename to replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/JarPatchInfo.groovy index 476109b3..c5596b4a 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/InjectorVersion.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/JarPatchInfo.groovy @@ -6,22 +6,22 @@ import com.qihoo360.replugin.gradle.plugin.AppConstant /** * @author 247321453 */ -public class InjectorVersion { +public class JarPatchInfo { def String jarMd5 def String pluginVersion - InjectorVersion(){ + JarPatchInfo(){ } - InjectorVersion(String jarMd5, String pluginVersion) { + JarPatchInfo(String jarMd5, String pluginVersion) { this.jarMd5 = jarMd5 this.pluginVersion = pluginVersion } - InjectorVersion(File jar){ + JarPatchInfo(File jar){ this.jarMd5 = Util.md5File(jar) this.pluginVersion = AppConstant.VER } diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/ReClassTransform.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/ReClassTransform.groovy index 2f257de6..4779051b 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/ReClassTransform.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/ReClassTransform.groovy @@ -83,6 +83,7 @@ public class ReClassTransform extends Transform { // Compatible with path separators for window and Linux, and fit split param based on 'Pattern.quote' def variantDir = rootLocation.absolutePath.split(getName() + Pattern.quote(File.separator))[1] println ">>> variantDir: ${variantDir}" + String buildType = variantDir; CommonData.appModule = config.appModule CommonData.ignoredActivities = config.ignoredActivities @@ -91,7 +92,7 @@ public class ReClassTransform extends Transform { if (injectors.isEmpty()) { copyResult(inputs, outputProvider) // 跳过 reclass } else { - doTransform(inputs, outputProvider, config, injectors) // 执行 reclass + doTransform(inputs, buildType, outputProvider, config, injectors) // 执行 reclass } } @@ -116,12 +117,13 @@ public class ReClassTransform extends Transform { * 执行 Transform */ def doTransform(Collection inputs, + buildType, TransformOutputProvider outputProvider, Object config, def injectors) { /* 初始化 ClassPool */ - Object pool = initClassPool(inputs) + Object pool = initClassPool(inputs, buildType) /* 进行注入操作 */ Util.newSection() @@ -207,11 +209,11 @@ public class ReClassTransform extends Transform { /** * 初始化 ClassPool */ - def initClassPool(Collection inputs) { + def initClassPool(Collection inputs,String buildType) { Util.newSection() def pool = new ClassPool(true) // 添加编译时需要引用的到类到 ClassPool, 同时记录要修改的 jar 到 includeJars - Util.getClassPaths(project, globalScope, inputs, includeJars, map).each { + Util.getClassPaths(project, buildType, globalScope, inputs, includeJars, map).each { println " $it" pool.insertClassPath(it) } diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy index f4e38fbe..7cecf1c2 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy @@ -47,14 +47,16 @@ public class Util { /** 生成 ClassPool 使用的 ClassPath 集合,同时将要处理的 jar 写入 includeJars */ def - static getClassPaths(Project project, GlobalScope globalScope, Collection inputs, Set includeJars, Map map) { + static getClassPaths(Project project, String buildType,GlobalScope globalScope, Collection inputs, Set includeJars, Map map) { def classpathList = [] + includeJars.clear() + // android.jar classpathList.add(getAndroidJarPath(globalScope)) // 原始项目中引用的 classpathList - getProjectClassPath(project, inputs, includeJars, map).each { + getProjectClassPath(project, buildType, inputs, includeJars, map).each { classpathList.add(it) } @@ -64,7 +66,7 @@ public class Util { } /** 获取原始项目中的 ClassPath */ - def private static getProjectClassPath(Project project, + def private static getProjectClassPath(Project project,String buildType, Collection inputs, Set includeJars, Map map) { def classPath = [] @@ -72,7 +74,9 @@ public class Util { def projectDir = project.getRootDir().absolutePath println ">>> Unzip Jar ..." - Map injectorMap = readJarInjectorHistory(project) + Map infoMap = readJarInjectorHistory(project, buildType) + final String injectDir = project.getBuildDir().path + + File.separator + FD_INTERMEDIATES + File.separator + "replugin-jar"+ File.separator + buildType; boolean needSave = false inputs.each { TransformInput input -> @@ -87,9 +91,9 @@ public class Util { input.jarInputs.each { JarInput jarInput -> File jar = jarInput.file def jarPath = jar.absolutePath - - if (!jarPath.contains(projectDir)) { - + if (jarPath.contains(File.separator + FD_INTERMEDIATES + File.separator + "replugin-jar")) { + // + }else if (!jarPath.contains(projectDir)) { String jarZipDir = project.getBuildDir().path + File.separator + FD_INTERMEDIATES + File.separator + "exploded-aar" + File.separator + Hashing.sha1().hashString(jarPath, Charsets.UTF_16LE).toString() + File.separator + "class"; @@ -101,70 +105,62 @@ public class Util { Files.walkFileTree(Paths.get(jarZipDir), visitor) map.put(jarPath, jarZip) } - } else { //重定向jar - if (jarPath.contains(File.separator + FD_INTERMEDIATES + File.separator + "replugin-jar")) { - // - } else { - String md5 = md5File(jar); - File reJar = new File(project.getBuildDir().path + - File.separator + FD_INTERMEDIATES + File.separator + "replugin-jar" - + File.separator + md5 + ".jar"); - String reJarPath = reJar.getAbsolutePath() - - boolean needInject = false - if (reJar.exists()) { - //检查修改插件版本 - InjectorVersion injectorVersion = injectorMap.get(jar.getAbsolutePath()); - if (injectorVersion != null) { - if (!AppConstant.VER.equals(injectorVersion.pluginVersion)) { - //版本变化了 + String md5 = md5File(jar); + File reJar = new File(injectDir + File.separator + md5 + ".jar"); + jarPath = reJar.getAbsolutePath() + + boolean needInject = false + if (reJar.exists()) { + //检查修改插件版本 + JarPatchInfo info = infoMap.get(jar.getAbsolutePath()); + if (info != null) { + if (!AppConstant.VER.equals(info.pluginVersion)) { + //版本变化了 + needInject = true + } else { + if (!md5.equals(info.jarMd5)) { + //原始jar内容变化 needInject = true - } else { - if (!md5.equals(injectorVersion.jarMd5)) { - //原始jar内容变化 - needInject = true - } } - } else { - //无记录 - needInject = true } } else { - FileUtils.copyFile(jar, reJar) - needInject = true; + //无记录 + needInject = true } - //设置重定向jar - setJarInput(jarInput, reJar) - if (needInject) { - includeJars << reJarPath - map.put(reJarPath, reJarPath) - - /* 将 jar 包解压,并将解压后的目录加入 classpath */ - // println ">>> 解压Jar${jarPath}" - String jarZipDir = reJar.getParent() + File.separatorChar + reJar.getName().replace('.jar', '') - if (unzip(jarPath, jarZipDir)) { - classPath << jarZipDir - //保存修改的插件版本号 - needSave = true - injectorMap.put(jar.getAbsolutePath(), new InjectorVersion(jar)) - - visitor.setBaseDir(jarZipDir) - Files.walkFileTree(Paths.get(jarZipDir), visitor) - } - // 删除 jar + } else { + needInject = true; + } + //设置重定向jar + setJarInput(jarInput, reJar) + if (needInject) { + /* 将 jar 包解压,并将解压后的目录加入 classpath */ + // println ">>> 解压Jar${jarPath}" + String jarZipDir = reJar.getParent() + File.separatorChar + reJar.getName().replace('.jar', '') + if (unzip(jar.getAbsolutePath(), jarZipDir)) { + + includeJars << jarPath + classPath << jarZipDir + //保存修改的插件版本号 + needSave = true + infoMap.put(jar.getAbsolutePath(), new JarPatchInfo(jar)) + + visitor.setBaseDir(jarZipDir) + Files.walkFileTree(Paths.get(jarZipDir), visitor) + + map.put(jarPath, jarPath) + } + // 删除 jar + if (reJar.exists()) { FileUtils.forceDelete(reJar) - } else { - map.remove(reJarPath) - includeJars.remove(reJarPath) } } } } } if (needSave) { - saveJarInjectorHistory(project, injectorMap) + saveJarInjectorHistory(project, buildType, infoMap) } return classPath } @@ -182,21 +178,21 @@ public class Util { /** * 读取修改jar的记录 */ - def static readJarInjectorHistory(Project project) { - File file = new File(project.getBuildDir(), FD_INTERMEDIATES - + File.separator + "replugin-jar" + File.separator + "version.json"); + def static readJarInjectorHistory(Project project, String buildType) { + final String dir = FD_INTERMEDIATES + File.separator + "replugin-jar"+ File.separator + buildType; + File file = new File(project.getBuildDir(), dir + File.separator + "version.json"); if (!file.exists()) { - return new HashMap(); + return new HashMap(); } Gson gson = new GsonBuilder() .create(); FileReader fileReader = new FileReader(file) JsonReader jsonReader = new JsonReader(fileReader); - Map injectorMap = gson.fromJson(jsonReader, new TypeToken>() { + Map injectorMap = gson.fromJson(jsonReader, new TypeToken>() { }.getType()); jsonReader.close() if (injectorMap == null) { - injectorMap = new HashMap(); + injectorMap = new HashMap(); } return injectorMap; } @@ -204,18 +200,18 @@ public class Util { /** * 保存修改jar的记录 */ - def static saveJarInjectorHistory(Project project, Map injectorMap) { + def static saveJarInjectorHistory(Project project,String buildType, Map injectorMap) { Gson gson = new GsonBuilder() .setPrettyPrinting() .create(); - File file = new File(project.getBuildDir(), FD_INTERMEDIATES - + File.separator + "replugin-jar" + File.separator + "version.json"); + final String dir = FD_INTERMEDIATES + File.separator + "replugin-jar"+ File.separator + buildType; + File file = new File(project.getBuildDir(), dir + File.separator + "version.json"); if (file.exists()) { file.delete() } else { - File dir = file.getParentFile(); - if (!dir.exists()) { - dir.mkdirs() + File p = file.getParentFile(); + if (!p.exists()) { + p.mkdirs() } } file.createNewFile() From c03c6aae1eae9ab11d5db47f674fda64fa09723b Mon Sep 17 00:00:00 2001 From: keyongyu Date: Mon, 21 Aug 2017 16:04:07 +0800 Subject: [PATCH 05/10] =?UTF-8?q?Activities=E5=8F=98=E5=8C=96=EF=BC=8C?= =?UTF-8?q?=E4=B9=9F=E9=9C=80=E8=A6=81=E6=9B=B4=E6=96=B0jar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gradle/plugin/inner/JarPatchInfo.groovy | 9 +++++++- .../replugin/gradle/plugin/inner/Util.groovy | 23 +++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/JarPatchInfo.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/JarPatchInfo.groovy index c5596b4a..b87a946a 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/JarPatchInfo.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/JarPatchInfo.groovy @@ -12,6 +12,8 @@ public class JarPatchInfo { def String pluginVersion + def String manifestActivitiesMd5 + JarPatchInfo(){ } @@ -21,8 +23,13 @@ public class JarPatchInfo { this.pluginVersion = pluginVersion } - JarPatchInfo(File jar){ + JarPatchInfo(File jar,String activitiesMd5){ this.jarMd5 = Util.md5File(jar) this.pluginVersion = AppConstant.VER + this.manifestActivitiesMd5 = activitiesMd5 + } + + JarPatchInfo(File jar){ + this(jar, null) } } diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy index 7cecf1c2..12c60105 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy @@ -27,6 +27,7 @@ import com.google.gson.Gson import com.google.gson.GsonBuilder import com.google.gson.stream.JsonReader import com.qihoo360.replugin.gradle.plugin.AppConstant +import com.qihoo360.replugin.gradle.plugin.manifest.ManifestAPI import org.apache.commons.codec.digest.DigestUtils import org.apache.commons.io.FileUtils import com.google.common.base.Charsets @@ -77,6 +78,22 @@ public class Util { Map infoMap = readJarInjectorHistory(project, buildType) final String injectDir = project.getBuildDir().path + File.separator + FD_INTERMEDIATES + File.separator + "replugin-jar"+ File.separator + buildType; + def activityList = new ArrayList<>(); + new ManifestAPI().getActivities(project, buildType).each { + // 处理没有被忽略的 Activity + if (!(it in CommonData.ignoredActivities)) { + // + activityList.add(it) + } + } + Collections.sort(activityList, new Comparator(){ + @Override + int compare(String o1, String o2) { + return o1.compareTo(o2); + } + }); + String activityMd5 = DigestUtils.md5Hex(activityList.toString()); + boolean needSave = false inputs.each { TransformInput input -> @@ -116,7 +133,9 @@ public class Util { //检查修改插件版本 JarPatchInfo info = infoMap.get(jar.getAbsolutePath()); if (info != null) { - if (!AppConstant.VER.equals(info.pluginVersion)) { + if(!activityMd5.equals(info.manifestActivitiesMd5)){ + needInject = true + }else if (!AppConstant.VER.equals(info.pluginVersion)) { //版本变化了 needInject = true } else { @@ -144,7 +163,7 @@ public class Util { classPath << jarZipDir //保存修改的插件版本号 needSave = true - infoMap.put(jar.getAbsolutePath(), new JarPatchInfo(jar)) + infoMap.put(jar.getAbsolutePath(), new JarPatchInfo(jar, activityMd5)) visitor.setBaseDir(jarZipDir) Files.walkFileTree(Paths.get(jarZipDir), visitor) From a4c067f778d87b41549f6bd896ea966e3c8714f9 Mon Sep 17 00:00:00 2001 From: keyongyu Date: Thu, 24 Aug 2017 14:25:29 +0800 Subject: [PATCH 06/10] =?UTF-8?q?aar=E7=9A=84jar=E9=83=BD=E4=B8=80?= =?UTF-8?q?=E6=A0=B7=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../replugin/gradle/plugin/inner/Util.groovy | 67 +++++++++---------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy index 12c60105..4625df5c 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy @@ -110,47 +110,14 @@ public class Util { def jarPath = jar.absolutePath if (jarPath.contains(File.separator + FD_INTERMEDIATES + File.separator + "replugin-jar")) { // - }else if (!jarPath.contains(projectDir)) { - String jarZipDir = project.getBuildDir().path + - File.separator + FD_INTERMEDIATES + File.separator + "exploded-aar" + - File.separator + Hashing.sha1().hashString(jarPath, Charsets.UTF_16LE).toString() + File.separator + "class"; - if (unzip(jarPath, jarZipDir)) { - def jarZip = jarZipDir + ".jar" - includeJars << jarPath - classPath << jarZipDir - visitor.setBaseDir(jarZipDir) - Files.walkFileTree(Paths.get(jarZipDir), visitor) - map.put(jarPath, jarZip) - } - } else { + }else{ //重定向jar String md5 = md5File(jar); File reJar = new File(injectDir + File.separator + md5 + ".jar"); jarPath = reJar.getAbsolutePath() - boolean needInject = false - if (reJar.exists()) { - //检查修改插件版本 - JarPatchInfo info = infoMap.get(jar.getAbsolutePath()); - if (info != null) { - if(!activityMd5.equals(info.manifestActivitiesMd5)){ - needInject = true - }else if (!AppConstant.VER.equals(info.pluginVersion)) { - //版本变化了 - needInject = true - } else { - if (!md5.equals(info.jarMd5)) { - //原始jar内容变化 - needInject = true - } - } - } else { - //无记录 - needInject = true - } - } else { - needInject = true; - } + boolean needInject = checkNeedInjector(infoMap, jar, reJar, activityMd5, md5); + //设置重定向jar setJarInput(jarInput, reJar) if (needInject) { @@ -194,6 +161,34 @@ public class Util { return md5 } + + def static checkNeedInjector( Map infoMap, File jar,File reJar,String activityMd5,String md5){ + boolean needInject = false + if (reJar.exists()) { + //检查修改插件版本 + JarPatchInfo info = infoMap.get(jar.getAbsolutePath()); + if (info != null) { + if(!activityMd5.equals(info.manifestActivitiesMd5)){ + needInject = true + }else if (!AppConstant.VER.equals(info.pluginVersion)) { + //版本变化了 + needInject = true + } else { + if (!md5.equals(info.jarMd5)) { + //原始jar内容变化 + needInject = true + } + } + } else { + //无记录 + needInject = true + } + } else { + needInject = true; + } + return needInject; + } + /** * 读取修改jar的记录 */ From d4853cbc832cc299649e795ddb727f9ed173f9dc Mon Sep 17 00:00:00 2001 From: keyongyu Date: Thu, 24 Aug 2017 15:23:35 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=E4=B8=8D=E9=9C=80=E8=A6=81=E5=8F=8D?= =?UTF-8?q?=E5=B0=84=E9=87=8D=E5=AE=9A=E5=90=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gradle/plugin/inner/ReClassTransform.groovy | 17 +++++++++++------ .../replugin/gradle/plugin/inner/Util.groovy | 8 ++++---- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/ReClassTransform.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/ReClassTransform.groovy index 4779051b..45d855c8 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/ReClassTransform.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/ReClassTransform.groovy @@ -177,13 +177,18 @@ public class ReClassTransform extends Transform { includeJars.each { File jar = new File(it) String JarAfterzip = map.get(jar.getParent() + File.separatorChar + jar.getName()) - String dirAfterUnzip = JarAfterzip.replace('.jar', '') - // println ">>> 压缩目录 $dirAfterUnzip" - - Util.zipDir(dirAfterUnzip, JarAfterzip) + if(JarAfterzip != null){ + String dirAfterUnzip = JarAfterzip.replace('.jar', '') + File dirAfterUnzipFile = new File(dirAfterUnzip); + if(dirAfterUnzipFile.exists()){ + // println ">>> 压缩目录 $dirAfterUnzip" - // println ">>> 删除目录 $dirAfterUnzip" - FileUtils.deleteDirectory(new File(dirAfterUnzip)) + Util.zipDir(dirAfterUnzip, JarAfterzip) + + // println ">>> 删除目录 $dirAfterUnzip" + FileUtils.deleteDirectory(dirAfterUnzipFile) + } + } } } diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy index 4625df5c..a0288828 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy @@ -119,14 +119,16 @@ public class Util { boolean needInject = checkNeedInjector(infoMap, jar, reJar, activityMd5, md5); //设置重定向jar - setJarInput(jarInput, reJar) +// setJarInput(jarInput, reJar) + //ReClassTransform.copyJar需要用到 + map.put(jar.getAbsolutePath(), jarPath) if (needInject) { /* 将 jar 包解压,并将解压后的目录加入 classpath */ // println ">>> 解压Jar${jarPath}" String jarZipDir = reJar.getParent() + File.separatorChar + reJar.getName().replace('.jar', '') if (unzip(jar.getAbsolutePath(), jarZipDir)) { - includeJars << jarPath + includeJars << jar.getAbsolutePath() classPath << jarZipDir //保存修改的插件版本号 needSave = true @@ -134,8 +136,6 @@ public class Util { visitor.setBaseDir(jarZipDir) Files.walkFileTree(Paths.get(jarZipDir), visitor) - - map.put(jarPath, jarPath) } // 删除 jar if (reJar.exists()) { From c2ca290713589cb190842ec4f8b0e05299dda0fe Mon Sep 17 00:00:00 2001 From: keyongyu <247321453@qq.com> Date: Sun, 27 Aug 2017 16:40:32 +0800 Subject: [PATCH 08/10] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gradle/plugin/inner/JarPatchInfo.groovy | 11 +- .../plugin/inner/ReClassTransform.groovy | 2 +- .../replugin/gradle/plugin/inner/Util.groovy | 130 ++++++++---------- 3 files changed, 62 insertions(+), 81 deletions(-) diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/JarPatchInfo.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/JarPatchInfo.groovy index b87a946a..e15c4862 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/JarPatchInfo.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/JarPatchInfo.groovy @@ -14,22 +14,17 @@ public class JarPatchInfo { def String manifestActivitiesMd5 + /** + * gson需要 + */ JarPatchInfo(){ } - JarPatchInfo(String jarMd5, String pluginVersion) { - this.jarMd5 = jarMd5 - this.pluginVersion = pluginVersion - } - JarPatchInfo(File jar,String activitiesMd5){ this.jarMd5 = Util.md5File(jar) this.pluginVersion = AppConstant.VER this.manifestActivitiesMd5 = activitiesMd5 } - JarPatchInfo(File jar){ - this(jar, null) - } } diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/ReClassTransform.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/ReClassTransform.groovy index 45d855c8..82fb73cf 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/ReClassTransform.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/ReClassTransform.groovy @@ -214,7 +214,7 @@ public class ReClassTransform extends Transform { /** * 初始化 ClassPool */ - def initClassPool(Collection inputs,String buildType) { + def initClassPool(Collection inputs, String buildType) { Util.newSection() def pool = new ClassPool(true) // 添加编译时需要引用的到类到 ClassPool, 同时记录要修改的 jar 到 includeJars diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy index a0288828..0b29f768 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy @@ -30,8 +30,6 @@ import com.qihoo360.replugin.gradle.plugin.AppConstant import com.qihoo360.replugin.gradle.plugin.manifest.ManifestAPI import org.apache.commons.codec.digest.DigestUtils import org.apache.commons.io.FileUtils -import com.google.common.base.Charsets -import com.google.common.hash.Hashing import org.gradle.api.Project import java.lang.reflect.Field @@ -39,8 +37,7 @@ import java.nio.file.Files import java.nio.file.Paths import java.util.zip.ZipFile -import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES; - +import static com.android.builder.model.AndroidProject.FD_INTERMEDIATES /** * @author RePlugin Team */ @@ -48,7 +45,7 @@ public class Util { /** 生成 ClassPool 使用的 ClassPath 集合,同时将要处理的 jar 写入 includeJars */ def - static getClassPaths(Project project, String buildType,GlobalScope globalScope, Collection inputs, Set includeJars, Map map) { + static getClassPaths(Project project, String buildType, GlobalScope globalScope, Collection inputs, Set includeJars, Map map) { def classpathList = [] includeJars.clear() @@ -67,32 +64,18 @@ public class Util { } /** 获取原始项目中的 ClassPath */ - def private static getProjectClassPath(Project project,String buildType, + def private static getProjectClassPath(Project project, String buildType, Collection inputs, Set includeJars, Map map) { def classPath = [] def visitor = new ClassFileVisitor() - def projectDir = project.getRootDir().absolutePath println ">>> Unzip Jar ..." Map infoMap = readJarInjectorHistory(project, buildType) final String injectDir = project.getBuildDir().path + File.separator + FD_INTERMEDIATES + File.separator + "replugin-jar"+ File.separator + buildType; - def activityList = new ArrayList<>(); - new ManifestAPI().getActivities(project, buildType).each { - // 处理没有被忽略的 Activity - if (!(it in CommonData.ignoredActivities)) { - // - activityList.add(it) - } - } - Collections.sort(activityList, new Comparator(){ - @Override - int compare(String o1, String o2) { - return o1.compareTo(o2); - } - }); - String activityMd5 = DigestUtils.md5Hex(activityList.toString()); + + String activityMd5 = genActivityMd5(project, buildType); boolean needSave = false inputs.each { TransformInput input -> @@ -108,39 +91,31 @@ public class Util { input.jarInputs.each { JarInput jarInput -> File jar = jarInput.file def jarPath = jar.absolutePath - if (jarPath.contains(File.separator + FD_INTERMEDIATES + File.separator + "replugin-jar")) { - // - }else{ - //重定向jar - String md5 = md5File(jar); - File reJar = new File(injectDir + File.separator + md5 + ".jar"); - jarPath = reJar.getAbsolutePath() - - boolean needInject = checkNeedInjector(infoMap, jar, reJar, activityMd5, md5); - - //设置重定向jar -// setJarInput(jarInput, reJar) - //ReClassTransform.copyJar需要用到 - map.put(jar.getAbsolutePath(), jarPath) - if (needInject) { - /* 将 jar 包解压,并将解压后的目录加入 classpath */ - // println ">>> 解压Jar${jarPath}" - String jarZipDir = reJar.getParent() + File.separatorChar + reJar.getName().replace('.jar', '') - if (unzip(jar.getAbsolutePath(), jarZipDir)) { - - includeJars << jar.getAbsolutePath() - classPath << jarZipDir - //保存修改的插件版本号 - needSave = true - infoMap.put(jar.getAbsolutePath(), new JarPatchInfo(jar, activityMd5)) - - visitor.setBaseDir(jarZipDir) - Files.walkFileTree(Paths.get(jarZipDir), visitor) - } - // 删除 jar - if (reJar.exists()) { - FileUtils.forceDelete(reJar) - } + + String md5 = md5File(jar); + File reJar = new File(injectDir + File.separator + md5 + ".jar"); + + boolean needInject = checkNeedInjector(infoMap, jar, reJar, activityMd5, md5); + + //ReClassTransform.copyJar需要用到 + map.put(jarPath, jar.getAbsolutePath()) + if (needInject) { + /* 将 jar 包解压,并将解压后的目录加入 classpath */ + // println ">>> 解压Jar${jarPath}" + String jarZipDir = reJar.getParent() + File.separatorChar + reJar.getName().replace('.jar', '') + if (unzip(jarPath, jarZipDir)) { + + includeJars << jarPath + classPath << jarZipDir + //保存修改的插件版本号 + needSave = true + infoMap.put(jarPath, new JarPatchInfo(jar, activityMd5)) + + visitor.setBaseDir(jarZipDir) + Files.walkFileTree(Paths.get(jarZipDir), visitor) + } + if (reJar.exists()) { + FileUtils.forceDelete(reJar) } } } @@ -151,6 +126,27 @@ public class Util { return classPath } + /** + * activities的md5 + */ + def static genActivityMd5(Project project, String buildType){ + def activityList = new ArrayList<>(); + new ManifestAPI().getActivities(project, buildType).each { + // 处理没有被忽略的 Activity + if (!(it in CommonData.ignoredActivities)) { + // + activityList.add(it) + } + } + Collections.sort(activityList, new Comparator(){ + @Override + int compare(String o1, String o2) { + return o1.compareTo(o2); + } + }); + return DigestUtils.md5Hex(activityList.toString()); + } + /** * 计算jar的md5 */ @@ -163,29 +159,19 @@ public class Util { def static checkNeedInjector( Map infoMap, File jar,File reJar,String activityMd5,String md5){ - boolean needInject = false + boolean needInject = true + if (reJar.exists()) { - //检查修改插件版本 JarPatchInfo info = infoMap.get(jar.getAbsolutePath()); if (info != null) { - if(!activityMd5.equals(info.manifestActivitiesMd5)){ - needInject = true - }else if (!AppConstant.VER.equals(info.pluginVersion)) { - //版本变化了 - needInject = true - } else { - if (!md5.equals(info.jarMd5)) { - //原始jar内容变化 - needInject = true - } + if (activityMd5.equals(info.manifestActivitiesMd5) + && AppConstant.VER.equals(info.pluginVersion) + && md5.equals(info.jarMd5)) { + needInject = false } - } else { - //无记录 - needInject = true } - } else { - needInject = true; } + return needInject; } From 0ca937c995c0e0b567d6e683e23b8449ef0d0f9b Mon Sep 17 00:00:00 2001 From: keyongyu <247321453@qq.com> Date: Sat, 2 Sep 2017 21:52:32 +0800 Subject: [PATCH 09/10] fix:repackage --- .../com/qihoo360/replugin/gradle/plugin/inner/Util.groovy | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy index 0b29f768..cbc69bee 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy @@ -94,11 +94,10 @@ public class Util { String md5 = md5File(jar); File reJar = new File(injectDir + File.separator + md5 + ".jar"); - boolean needInject = checkNeedInjector(infoMap, jar, reJar, activityMd5, md5); //ReClassTransform.copyJar需要用到 - map.put(jarPath, jar.getAbsolutePath()) + map.put(jarPath, reJar.getAbsolutePath()) if (needInject) { /* 将 jar 包解压,并将解压后的目录加入 classpath */ // println ">>> 解压Jar${jarPath}" From a49598f586e1ed4d8e481ac697ff4309c42d6ec5 Mon Sep 17 00:00:00 2001 From: keyongyu <247321453@qq.com> Date: Sun, 3 Sep 2017 13:59:23 +0800 Subject: [PATCH 10/10] code:reJarPath --- .../replugin/gradle/plugin/inner/Util.groovy | 44 +++++-------------- 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy index cbc69bee..486ce94e 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/Util.groovy @@ -32,7 +32,6 @@ import org.apache.commons.codec.digest.DigestUtils import org.apache.commons.io.FileUtils import org.gradle.api.Project -import java.lang.reflect.Field import java.nio.file.Files import java.nio.file.Paths import java.util.zip.ZipFile @@ -71,11 +70,11 @@ public class Util { def visitor = new ClassFileVisitor() println ">>> Unzip Jar ..." - Map infoMap = readJarInjectorHistory(project, buildType) - final String injectDir = project.getBuildDir().path + + def infoMap = readJarInjectorHistory(project, buildType) + final def injectDir = project.getBuildDir().path + File.separator + FD_INTERMEDIATES + File.separator + "replugin-jar"+ File.separator + buildType; - String activityMd5 = genActivityMd5(project, buildType); + def activityMd5 = genActivityMd5(project, buildType); boolean needSave = false inputs.each { TransformInput input -> @@ -89,19 +88,20 @@ public class Util { } input.jarInputs.each { JarInput jarInput -> - File jar = jarInput.file + def jar = jarInput.file def jarPath = jar.absolutePath - String md5 = md5File(jar); - File reJar = new File(injectDir + File.separator + md5 + ".jar"); + def md5 = md5File(jar); + def reJar = new File(injectDir + File.separator + md5 + ".jar"); + def reJarPath = reJar.getAbsolutePath() boolean needInject = checkNeedInjector(infoMap, jar, reJar, activityMd5, md5); //ReClassTransform.copyJar需要用到 - map.put(jarPath, reJar.getAbsolutePath()) + map.put(jarPath, reJarPath) if (needInject) { /* 将 jar 包解压,并将解压后的目录加入 classpath */ // println ">>> 解压Jar${jarPath}" - String jarZipDir = reJar.getParent() + File.separatorChar + reJar.getName().replace('.jar', '') + def jarZipDir = reJar.getParent() + File.separatorChar + reJar.getName().replace('.jar', '') if (unzip(jarPath, jarZipDir)) { includeJars << jarPath @@ -150,8 +150,8 @@ public class Util { * 计算jar的md5 */ def static md5File(File jar) { - FileInputStream fileInputStream = new FileInputStream(jar); - String md5 = DigestUtils.md5Hex(fileInputStream); + def fileInputStream = new FileInputStream(jar); + def md5 = DigestUtils.md5Hex(fileInputStream); fileInputStream.close() return md5 } @@ -161,7 +161,7 @@ public class Util { boolean needInject = true if (reJar.exists()) { - JarPatchInfo info = infoMap.get(jar.getAbsolutePath()); + def info = infoMap.get(jar.getAbsolutePath()); if (info != null) { if (activityMd5.equals(info.manifestActivitiesMd5) && AppConstant.VER.equals(info.pluginVersion) @@ -220,26 +220,6 @@ public class Util { fileWriter.close() } - /** - * 反射,修改引用的jar路径 - */ - def static setJarInput(JarInput jarInput, File rejar) { - Field fileField = null; - Class clazz = jarInput.getClass(); - while (fileField == null && clazz != Object.class) { - try { - fileField = clazz.getDeclaredField("file"); - } catch (Exception e) { - //ignore - clazz = clazz.getSuperclass(); - } - } - if (fileField != null) { - fileField.setAccessible(true); - fileField.set(jarInput, rejar); - } - } - /** * 编译环境中 android.jar 的路径 */