Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

优化插件工程处理jar、修改复制so文件时的abi匹配逻辑 #667

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,9 @@ private static String findSoPathForAbis(Set<String> soPaths, String soName) {
}

private static String findSoPathWithAbiList(Set<String> 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;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Path>() {
@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)
}
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -77,6 +78,9 @@ public class LoaderActivityInjector extends BaseInjector {
}

println ">>> Handle $activity"
if (InjectHistory.contains(project, clsFilePath)) {
return
}

def stream, ctCls
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public class ReClassTransform extends Transform {
} else {
doTransform(inputs, outputProvider, config, injectors) // 执行 reclass
}
InjectHistory.save(project)
}

/**
Expand Down Expand Up @@ -182,6 +183,7 @@ public class ReClassTransform extends Transform {

// println ">>> 删除目录 $dirAfterUnzip"
FileUtils.deleteDirectory(new File(dirAfterUnzip))
InjectHistory.put(project, JarAfterzip)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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)) {

Expand Down Expand Up @@ -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<Path>(){
@Override
FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (!classPath.contains(file.toString())) {
classPath << file.toString()
}
return super.visitFile(file, attrs)
}
})
}
return classPath
}

Expand Down