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 #301

Open
wants to merge 10 commits into
base: dev
Choose a base branch
from
Open

重定向修改jar #301

wants to merge 10 commits into from

Conversation

247321453
Copy link

引用的jar,重定向到build下面修改过的jar,版本信息存在version.json

/* 将 jar 包解压,并将解压后的目录加入 classpath */
// println ">>> 解压Jar${jarPath}"
String jarZipDir = reJar.getParent() + File.separatorChar + reJar.getName().replace('.jar', '')
if (unzip(jarPath, jarZipDir)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在原逻辑中的unzip(...)之前所新增的以上全部代码,都可以封装到一个isNeedInject(...)方法中,这样这块核心逻辑分支会整洁很多。

}
//设置重定向jar
setJarInput(jarInput, reJar)
if (needInject) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

目前看,只在一种buildType下会去动态编译,后续依次编译其他buildType时,就不会去动态编译了。这样是存在潜在问题的,比如用户指定了不同buildType下的manifest中包含有不同acitivity,那么就可能存在这样一种情况:

  • 场景
    debug下manifest中注册了Activity A,其中A在test.jar中包含。
    release下manifest中注册了Activity B,其中B在test.jar中包含。
  • 结果
    编译debug时,对test.jar中 A的顶级父类做了替换。
    编译release时,不再对test.jar进行动态编译,test.jar中的Activity B的顶级父类并未做替换。

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个的确

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

还有一种case,就是一次完整的buildtype遍历编译完成后,用户在manifest中新增注册了jar中的某个Activity,那也会出现不替换jar中的对应顶级父类的情况

needInject = true
}
} else {
FileUtils.copyFile(jar, reJar)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

拷贝jar是不必要的。可以参考源码中对非项目目录下的jar的解压方式。

needInject = true;
}
//设置重定向jar
setJarInput(jarInput, reJar)
Copy link
Contributor

@wangfuda wangfuda Aug 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

通过反射方式,修改gradle的transform.JarInput字段的重定向jar是不必要的。(实际上可以在不改动默认编译流程的前提下,实现功能。如有疑问,可以私信交流哈)

setJarInput(jarInput, reJar)
if (needInject) {
includeJars << reJarPath
map.put(reJarPath, reJarPath)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里还请与其他jar处理逻辑分支保持一致,保存的是orginal 'jarPath'

boolean needInject = false
if (reJar.exists()) {
//检查修改插件版本
InjectorVersion injectorVersion = injectorMap.get(jar.getAbsolutePath());
Copy link
Contributor

@wangfuda wangfuda Aug 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里方法和变量的命名,还是建议更精准一些,比如InjectorVersion ,里面包含了插件版本信息,和jar的md5信息,类名建议叫JarInfo(或者有更确切的名字也可以),包括injectorMap也建议修改为jarInfoMap,这部分相关的代码和类名尽量不带‘injector’字样,毕竟‘injector’的本意是注入器,这只应该injector模块及相关部分中使用。
另:json文件也建议与此保持一致,这样代码整体一致性更强些。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

或者类名叫BuildCacheInfo,更确切些,供参考


def String jarMd5

def String pluginVersion

InjectorVersion(){
JarPatchInfo(){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

无用的import和方法,变量声明等,请移除


}

InjectorVersion(String jarMd5, String pluginVersion) {
JarPatchInfo(String jarMd5, String pluginVersion) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

无用的import和方法,变量声明等,请移除

this.jarMd5 = jarMd5
this.pluginVersion = pluginVersion
}

InjectorVersion(File jar){
JarPatchInfo(File jar){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

无用的import和方法,变量声明等,请移除

@@ -207,11 +209,11 @@ public class ReClassTransform extends Transform {
/**
* 初始化 ClassPool
*/
def initClassPool(Collection<TransformInput> inputs) {
def initClassPool(Collection<TransformInput> inputs,String buildType) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

此行代码格式化一下

@@ -47,14 +47,16 @@ public class Util {

/** 生成 ClassPool 使用的 ClassPath 集合,同时将要处理的 jar 写入 includeJars */
def
static getClassPaths(Project project, GlobalScope globalScope, Collection<TransformInput> inputs, Set<String> includeJars, Map<String, String> map) {
static getClassPaths(Project project, String buildType,GlobalScope globalScope, Collection<TransformInput> inputs, Set<String> includeJars, Map<String, String> map) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

代码格式化

//版本变化了
String md5 = md5File(jar);
File reJar = new File(injectDir + File.separator + md5 + ".jar");
jarPath = reJar.getAbsolutePath()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里不要复用之前的jarPath 变量,重新定义个reJarPath

@@ -119,23 +119,23 @@ public class Util {
boolean needInject = checkNeedInjector(infoMap, jar, reJar, activityMd5, md5);

//设置重定向jar
setJarInput(jarInput, reJar)
// setJarInput(jarInput, reJar)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

无用的import和方法,变量声明等,请移除

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()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

保持原代码不变,jarPath已经获取了全路径。相关代码需要调整下

}
return needInject;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

代码逻辑可以精简为:

def static checkNeedInjector(Map<String, JarPatchInfo> infoMap, File jar, File reJar, String activityMd5, String md5) {

        boolean needInject = true

        if (reJar.exists()) {
            JarPatchInfo info = infoMap.get(jar.getAbsolutePath());
            if (info != null) {
                if (activityMd5.equals(info.manifestActivitiesMd5)
                        && AppConstant.VER.equals(info.pluginVersion)
                        && md5.equals(info.jarMd5)) {
                    needInject = false
                }
            }
        }

        return needInject;
    }

map.put(jarPath, jarZip)
}
} else {
}else{
//重定向jar
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里严格说,不是重定向文件,只是将文件解压到临时目录。请移除该注释。

@wangfuda
Copy link
Contributor

review及test case均已pass,请merge

@jiongxuan
Copy link
Contributor

非常好。其实 @wangfuda 你也可以直接点Merge的 :) (我一开始以为你还在Review,哈哈)

那我就Merge进来了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants