diff --git a/gson_plugin/src/main/groovy/com/ke/gson/plugin/GsonPlugin.groovy b/gson_plugin/src/main/groovy/com/ke/gson/plugin/GsonPlugin.groovy index b16fccb..b9f80e9 100644 --- a/gson_plugin/src/main/groovy/com/ke/gson/plugin/GsonPlugin.groovy +++ b/gson_plugin/src/main/groovy/com/ke/gson/plugin/GsonPlugin.groovy @@ -19,7 +19,7 @@ class GsonPlugin implements Plugin { } // add dependencies - project.dependencies.add("compile", + project.dependencies.add("api", "com.github.LianjiaTech:gson-plugin-sdk:1.0.0") // register transform diff --git a/gson_plugin/src/main/groovy/com/ke/gson/plugin/inject/jar/InjectGsonJar.groovy b/gson_plugin/src/main/groovy/com/ke/gson/plugin/inject/jar/InjectGsonJar.groovy index 55bbab3..6b7a055 100644 --- a/gson_plugin/src/main/groovy/com/ke/gson/plugin/inject/jar/InjectGsonJar.groovy +++ b/gson_plugin/src/main/groovy/com/ke/gson/plugin/inject/jar/InjectGsonJar.groovy @@ -1,8 +1,10 @@ package com.ke.gson.plugin.inject.jar import com.android.build.api.transform.Context +import com.android.build.api.transform.JarInput import com.ke.gson.plugin.inject.jar.adapter.InjectArrayTypeAdapter import com.ke.gson.plugin.inject.jar.adapter.InjectCollectionTypeAdapterFactory +import com.ke.gson.plugin.inject.jar.adapter.InjectGsonTypeAdapter import com.ke.gson.plugin.inject.jar.adapter.InjectTypeAdapters import com.ke.gson.plugin.inject.jar.adapter.InjectMapTypeAdapterFactory import com.ke.gson.plugin.inject.jar.adapter.InjectReflectiveTypeAdapterFactory @@ -18,8 +20,10 @@ import org.gradle.api.Project class InjectGsonJar { - public static File inject(File jarFile, Context context, Project project) throws NotFoundException { - if (!jarFile.name.contains("gson")) { + public static File inject(JarInput jarInput, Context context, Project project) throws NotFoundException { + def jarInputName = jarInput.name + File jarFile = jarInput.file + if (!jarFile.name.startsWith("gson") && !jarInputName.startsWith("com.google.code.gson:gson")) { return null } println("GsonPlugin: inject gson jar start") @@ -42,6 +46,7 @@ class InjectGsonJar { InjectArrayTypeAdapter.inject(tmpDirPath) InjectCollectionTypeAdapterFactory.inject(tmpDirPath) InjectTypeAdapters.inject(tmpDirPath) + InjectGsonTypeAdapter.inject(tmpDirPath) //重新压缩 Compressor.compress(tmpDirPath, targetPath) diff --git a/gson_plugin/src/main/groovy/com/ke/gson/plugin/inject/jar/adapter/InjectGsonTypeAdapter.groovy b/gson_plugin/src/main/groovy/com/ke/gson/plugin/inject/jar/adapter/InjectGsonTypeAdapter.groovy new file mode 100644 index 0000000..94e2b39 --- /dev/null +++ b/gson_plugin/src/main/groovy/com/ke/gson/plugin/inject/jar/adapter/InjectGsonTypeAdapter.groovy @@ -0,0 +1,48 @@ +package com.ke.gson.plugin.inject.jar.adapter + +import com.ke.gson.plugin.global.MyClassPool +import javassist.ClassPool +import javassist.CtClass +import javassist.CtMethod + +/** + * Created by tangfuling on 2018/10/30. + */ + +public class InjectGsonTypeAdapter { + + public static void inject(String dirPath) { + + ClassPool classPool = MyClassPool.getClassPool() + + File dir = new File(dirPath) + if (dir.isDirectory()) { + dir.eachFileRecurse { File file -> + if (file.name.startsWith("Gson\$")) { + String innerClassName = file.name.substring(5, file.name.length() - 6) + CtClass ctClass = classPool.getCtClass("com.google.gson.Gson\$" + innerClassName) + //only deal type Number Double Float + CtMethod[] methods = ctClass.declaredMethods + boolean isModified = false + for (CtMethod ctMethod : methods) { + if ("read".equals(ctMethod.name)) { + String returnTypeName = ctMethod.getReturnType().name + if ("java.lang.Number".equals(returnTypeName) + || "java.lang.Double".equals(returnTypeName) + || "java.lang.Float".equals(returnTypeName)) { + CtClass etype = classPool.get("java.lang.Exception") + ctMethod.addCatch("{com.ke.gson.sdk.ReaderTools.onJsonTokenParseException(\$1, \$e); return null;}", etype) + isModified = true + } + } + } + if (isModified) { + ctClass.writeFile(dirPath) + println("GsonPlugin: inject GsonTypeAdapter success") + } + ctClass.detach() + } + } + } + } +} diff --git a/gson_plugin/src/main/groovy/com/ke/gson/plugin/inject/jar/adapter/InjectTypeAdapters.groovy b/gson_plugin/src/main/groovy/com/ke/gson/plugin/inject/jar/adapter/InjectTypeAdapters.groovy index e559ffd..4a37457 100644 --- a/gson_plugin/src/main/groovy/com/ke/gson/plugin/inject/jar/adapter/InjectTypeAdapters.groovy +++ b/gson_plugin/src/main/groovy/com/ke/gson/plugin/inject/jar/adapter/InjectTypeAdapters.groovy @@ -18,17 +18,18 @@ public class InjectTypeAdapters { File dir = new File(dirPath) if (dir.isDirectory()) { dir.eachFileRecurse { File file -> - if (file.name.contains("TypeAdapters\$")) { + if (file.name.startsWith("TypeAdapters\$")) { String innerClassName = file.name.substring(13, file.name.length() - 6) CtClass ctClass = classPool.getCtClass("com.google.gson.internal.bind.TypeAdapters\$" + innerClassName) - //only deal type Boolean and Number + //only deal type Number Boolean String CtMethod[] methods = ctClass.declaredMethods boolean isModified = false for (CtMethod ctMethod : methods) { if ("read".equals(ctMethod.name)) { String returnTypeName = ctMethod.getReturnType().name if ("java.lang.Number".equals(returnTypeName) - || "java.lang.Boolean".equals(returnTypeName)) { + || "java.lang.Boolean".equals(returnTypeName) + || "java.lang.String".equals(returnTypeName)) { CtClass etype = classPool.get("java.lang.Exception") ctMethod.addCatch("{com.ke.gson.sdk.ReaderTools.onJsonTokenParseException(\$1, \$e); return null;}", etype) isModified = true diff --git a/gson_plugin/src/main/groovy/com/ke/gson/plugin/transform/GsonJarTransform.groovy b/gson_plugin/src/main/groovy/com/ke/gson/plugin/transform/GsonJarTransform.groovy index 9645e68..8da49bb 100644 --- a/gson_plugin/src/main/groovy/com/ke/gson/plugin/transform/GsonJarTransform.groovy +++ b/gson_plugin/src/main/groovy/com/ke/gson/plugin/transform/GsonJarTransform.groovy @@ -51,18 +51,18 @@ class GsonJarTransform extends Transform { for (TransformInput input : transformInvocation.getInputs()) { for (JarInput jarInput : input.getJarInputs()) { // name must be unique,or throw exception "multiple dex files define" - def jarName = jarInput.name - if (jarName.endsWith('.jar')) { - jarName = jarName.substring(0, jarName.length() - 4) + def jarInputName = jarInput.name + if (jarInputName.endsWith('.jar')) { + jarInputName = jarInputName.substring(0, jarInputName.length() - 4) } def md5Name = DigestUtils.md5Hex(jarInput.file.getAbsolutePath()) //source file - File file = InjectGsonJar.inject(jarInput.file, transformInvocation.context, mProject) + File file = InjectGsonJar.inject(jarInput, transformInvocation.context, mProject) if (file == null) { file = jarInput.file } //dest file - File dest = outputProvider.getContentLocation(jarName + md5Name, + File dest = outputProvider.getContentLocation(jarInputName + md5Name, jarInput.contentTypes, jarInput.scopes, Format.JAR) FileUtils.copyFile(file, dest) }