diff --git a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/PluginNativeLibsHelper.java b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/PluginNativeLibsHelper.java index e67fbe50..81c0b03a 100644 --- a/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/PluginNativeLibsHelper.java +++ b/replugin-host-library/replugin-host-lib/src/main/java/com/qihoo360/loader2/PluginNativeLibsHelper.java @@ -185,12 +185,9 @@ private static String findSoPathForAbis(Set soPaths, String soName) { } private static String findSoPathWithAbiList(Set soPaths, String soName, String[] supportAbis) { - Arrays.sort(supportAbis); - for (String soPath : soPaths) { - String abi = soPath.replaceFirst("lib/", ""); - abi = abi.replace("/" + soName, ""); - - if (!TextUtils.isEmpty(abi) && Arrays.binarySearch(supportAbis, abi) >= 0) { + for (String abi : supportAbis) { + String soPath = "lib/" + abi + "/" + soName; + if (soPaths.contains(soPath)) { return soPath; } } diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/HistoryInjector.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/HistoryInjector.groovy new file mode 100644 index 00000000..a214df0c --- /dev/null +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/HistoryInjector.groovy @@ -0,0 +1,36 @@ +package com.qihoo360.replugin.gradle.plugin.injector + +import com.qihoo360.replugin.gradle.plugin.inner.InjectHistory +import com.qihoo360.replugin.gradle.plugin.inner.Util +import javassist.ClassPool + +import java.nio.file.FileVisitResult +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths +import java.nio.file.SimpleFileVisitor +import java.nio.file.attribute.BasicFileAttributes + +/** + * 放在Injectors的末尾,所有其它injector执行完成后遍历文件,记录到InjectHistory里 + * @author jsh + */ +public class HistoryInjector extends BaseInjector { + + @Override + def injectClass(ClassPool pool, String dir, Map config) { + Util.newSection() + println dir + + Files.walkFileTree(Paths.get(dir), new SimpleFileVisitor() { + @Override + FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + + //todo only .class + String filePath = file.toString() + InjectHistory.put(project, filePath) + return super.visitFile(file, attrs) + } + }) + } +} \ No newline at end of file diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/Injectors.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/Injectors.groovy index d63e1c2f..4dfd6fb4 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/Injectors.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/Injectors.groovy @@ -32,7 +32,8 @@ public enum Injectors { LOCAL_BROADCAST_INJECTOR('LocalBroadcastInjector', new LocalBroadcastInjector(), '替换 LocalBroadcast 调用'), PROVIDER_INJECTOR('ProviderInjector', new ProviderInjector(), '替换 Provider 调用'), PROVIDER_INJECTOR2('ProviderInjector2', new ProviderInjector2(), '替换 ContentProviderClient 调用'), - GET_IDENTIFIER_INJECTOR('GetIdentifierInjector', new GetIdentifierInjector(), '替换 Resource.getIdentifier 调用') + GET_IDENTIFIER_INJECTOR('GetIdentifierInjector', new GetIdentifierInjector(), '替换 Resource.getIdentifier 调用'), + HISTORY_INJECTOR('HistoryInjector', new HistoryInjector(), '记录处理过的class文件') IClassInjector injector String nickName diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/identifier/GetIdentifierInjector.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/identifier/GetIdentifierInjector.groovy index 820e6afb..90a730e6 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/identifier/GetIdentifierInjector.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/identifier/GetIdentifierInjector.groovy @@ -18,6 +18,7 @@ package com.qihoo360.replugin.gradle.plugin.injector.identifier import com.qihoo360.replugin.gradle.plugin.injector.BaseInjector +import com.qihoo360.replugin.gradle.plugin.inner.InjectHistory import com.qihoo360.replugin.gradle.plugin.inner.Util import javassist.ClassPool @@ -48,6 +49,9 @@ public class GetIdentifierInjector extends BaseInjector { //todo only .class String filePath = file.toString() + if (InjectHistory.contains(project, filePath)) { + return super.visitFile(file, attrs) + } editor.filePath = filePath diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/loaderactivity/LoaderActivityInjector.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/loaderactivity/LoaderActivityInjector.groovy index 059fd158..ef97f02f 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/loaderactivity/LoaderActivityInjector.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/loaderactivity/LoaderActivityInjector.groovy @@ -19,6 +19,7 @@ package com.qihoo360.replugin.gradle.plugin.injector.loaderactivity import com.qihoo360.replugin.gradle.plugin.injector.BaseInjector import com.qihoo360.replugin.gradle.plugin.inner.CommonData +import com.qihoo360.replugin.gradle.plugin.inner.InjectHistory import com.qihoo360.replugin.gradle.plugin.manifest.ManifestAPI import javassist.CannotCompileException import javassist.ClassPool @@ -77,6 +78,9 @@ public class LoaderActivityInjector extends BaseInjector { } println ">>> Handle $activity" + if (InjectHistory.contains(project, clsFilePath)) { + return + } def stream, ctCls try { diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/localbroadcast/LocalBroadcastInjector.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/localbroadcast/LocalBroadcastInjector.groovy index fcf297cd..f26b21da 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/localbroadcast/LocalBroadcastInjector.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/localbroadcast/LocalBroadcastInjector.groovy @@ -18,6 +18,7 @@ package com.qihoo360.replugin.gradle.plugin.injector.localbroadcast import com.qihoo360.replugin.gradle.plugin.injector.BaseInjector +import com.qihoo360.replugin.gradle.plugin.inner.InjectHistory import com.qihoo360.replugin.gradle.plugin.inner.Util import javassist.ClassPool @@ -61,6 +62,9 @@ public class LocalBroadcastInjector extends BaseInjector { String filePath = file.toString() editor.filePath = filePath + if (InjectHistory.contains(project, filePath)) { + return super.visitFile(file, attrs) + } def stream, ctCls try { // 不处理 LocalBroadcastManager.class diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/provider/ProviderInjector.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/provider/ProviderInjector.groovy index c853ef49..39b294ff 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/provider/ProviderInjector.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/provider/ProviderInjector.groovy @@ -17,6 +17,7 @@ package com.qihoo360.replugin.gradle.plugin.injector.provider +import com.qihoo360.replugin.gradle.plugin.inner.InjectHistory import com.qihoo360.replugin.gradle.plugin.inner.Util import com.qihoo360.replugin.gradle.plugin.injector.BaseInjector import javassist.ClassPool @@ -70,6 +71,9 @@ public class ProviderInjector extends BaseInjector { FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { String filePath = file.toString() + if (InjectHistory.contains(project, filePath)) { + return super.visitFile(file, attrs) + } def stream, ctCls try { diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/provider/ProviderInjector2.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/provider/ProviderInjector2.groovy index 400ac42a..f139817a 100644 --- a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/provider/ProviderInjector2.groovy +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/provider/ProviderInjector2.groovy @@ -17,6 +17,7 @@ package com.qihoo360.replugin.gradle.plugin.injector.provider +import com.qihoo360.replugin.gradle.plugin.inner.InjectHistory import com.qihoo360.replugin.gradle.plugin.inner.Util import com.qihoo360.replugin.gradle.plugin.injector.BaseInjector import javassist.ClassPool @@ -58,6 +59,9 @@ public class ProviderInjector2 extends BaseInjector { FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { String filePath = file.toString() + if (InjectHistory.contains(project, filePath)) { + return super.visitFile(file, attrs) + } def stream, ctCls try { diff --git a/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/InjectHistory.groovy b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/InjectHistory.groovy new file mode 100644 index 00000000..364d6db5 --- /dev/null +++ b/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/inner/InjectHistory.groovy @@ -0,0 +1,82 @@ +package com.qihoo360.replugin.gradle.plugin.inner + +import org.gradle.api.Project + +import java.security.MessageDigest + +/** + * 记录已经修改过的文件,避免重复操作 + */ +public class InjectHistory { + def static final PROP_FILE = "injectHistory.prop" + + def static history = null as Properties + + def static boolean contains(Project project, String filePath) { + initHistory(project) + //test + String key = getKey(project, filePath) + String value = history.get(key) + if (value == null) { + return false + } + String md5 = getMd5(new File(filePath)) + return value == md5 + } + + def private static String getKey(Project project, String filePath){ + return filePath.replace(project.buildDir.absolutePath + "\\intermediates\\classes\\", "") + } + def static void put(Project project, String filePath) { + initHistory(project) + //不记录libs下jar解压后的class、png等(有的jar有assets),因为以后编译时直接忽略jar + if (!filePath.endsWith(".jar") && filePath.startsWith(new File(project.projectDir, "libs").absolutePath)) { + return + } + //不记录provided下的jar解压后的class、png等 + if (!filePath.endsWith(".jar") && filePath.startsWith(new File(project.projectDir, "provided").absolutePath)) { + return + } + + String md5 = getMd5(new File(filePath)) + String key = getKey(project, filePath) + history.put(key, md5) + //println("InjectHistory put " + filePath + " -----> " + md5) + } + + def static void save(Project project) { + if (history != null) { + history.store(new File(project.projectDir.absolutePath, PROP_FILE).newWriter(), null) + //每次执行完成后都清除"缓存",下次执行时从文件加载。删除文件可以强制重新执行 + history.clear() + } + } + + def private static void initHistory(Project project) { + if (history == null) { + history = new Properties() + } + if (history.isEmpty()) { + def projectDir = project.getProjectDir().absolutePath + File historyFile = new File(projectDir, PROP_FILE) + if (!historyFile.exists()) { + historyFile.createNewFile() + } + try { + historyFile.withInputStream { + history.load(it) + } + } catch (Exception e) { + e.printStackTrace() + } + } + } + + def static String getMd5(File file) { + def digest = MessageDigest.getInstance("MD5") + file.eachByte(4096) { buffer, length -> + digest.update(buffer, 0, length) + } + digest.digest().encodeHex() as String + } +} \ No newline at end of file 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..256a37c8 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 @@ -93,6 +93,7 @@ public class ReClassTransform extends Transform { } else { doTransform(inputs, outputProvider, config, injectors) // 执行 reclass } + InjectHistory.save(project) } /** @@ -182,6 +183,7 @@ public class ReClassTransform extends Transform { // println ">>> 删除目录 $dirAfterUnzip" FileUtils.deleteDirectory(new File(dirAfterUnzip)) + InjectHistory.put(project, JarAfterzip) } } 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..0049f673 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,17 +22,20 @@ 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 org.apache.commons.io.FileUtils import com.google.common.base.Charsets import com.google.common.hash.Hashing +import org.apache.commons.io.FileUtils import org.gradle.api.Project +import java.nio.file.FileVisitResult import java.nio.file.Files +import java.nio.file.Path import java.nio.file.Paths +import java.nio.file.SimpleFileVisitor +import java.nio.file.attribute.BasicFileAttributes 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 */ @@ -79,6 +82,14 @@ public class Util { input.jarInputs.each { JarInput jarInput -> File jar = jarInput.file def jarPath = jar.absolutePath + println("getProjectClassPth--jarPath=" + jarPath) + //todo jar只需要处理一次,以后忽略 + if (InjectHistory.contains(project, jarPath)){ + //虽然忽略jar,但仍然要添加到classpath里 + classPath << jarPath + println("ignore jar " + jarPath) + return + } if (!jarPath.contains(projectDir)) { @@ -114,6 +125,20 @@ public class Util { } } } + + //fixme 先写死,以后读取gradle配置 + File providedDir = new File(project.projectDir, "provided") + if (providedDir.exists() && providedDir.isDirectory()) { + Files.walkFileTree(Paths.get(providedDir.absolutePath), new SimpleFileVisitor(){ + @Override + FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (!classPath.contains(file.toString())) { + classPath << file.toString() + } + return super.visitFile(file, attrs) + } + }) + } return classPath }