Skip to content

Commit

Permalink
feature:1.修改对gson-sdk引用为api避免warning; 2.在lib包中加入gson或通过dependence加入gs…
Browse files Browse the repository at this point in the history
…on均可生效; 3.支持Object、Array、Map、Boolean、Number、Double、Float、String等多种数据类型的兼容
  • Loading branch information
lianjia\tangfuling committed May 13, 2019
1 parent 9e77871 commit 995a762
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class GsonPlugin implements Plugin<Project> {
}

// add dependencies
project.dependencies.add("compile",
project.dependencies.add("api",
"com.github.LianjiaTech:gson-plugin-sdk:1.0.0")

// register transform
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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")
Expand All @@ -42,6 +46,7 @@ class InjectGsonJar {
InjectArrayTypeAdapter.inject(tmpDirPath)
InjectCollectionTypeAdapterFactory.inject(tmpDirPath)
InjectTypeAdapters.inject(tmpDirPath)
InjectGsonTypeAdapter.inject(tmpDirPath)

//重新压缩
Compressor.compress(tmpDirPath, targetPath)
Expand Down
Original file line number Diff line number Diff line change
@@ -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()
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down

0 comments on commit 995a762

Please sign in to comment.