mirror of
https://github.com/QM4RS/FridaBox.git
synced 2026-10-04 23:12:18 +02:00
feat: Introduce black-reflection and compiler modules, integrate reflection utilities, and update core components.
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
package top.niunaijun.blackreflection;
|
||||
|
||||
|
||||
public class BlackReflectionInfo {
|
||||
// 反射指向的类
|
||||
private String realClass;
|
||||
// 当前注解的className
|
||||
private String className;
|
||||
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
public void setClassName(String className) {
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
public String getRealClass() {
|
||||
return realClass;
|
||||
}
|
||||
|
||||
public void setRealClass(String realClass) {
|
||||
this.realClass = realClass;
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package top.niunaijun.blackreflection;
|
||||
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
|
||||
|
||||
public class BlackReflectionInterfaceInfo {
|
||||
// 方法element
|
||||
private ExecutableElement executableElement;
|
||||
// 是否是字段
|
||||
private boolean isField;
|
||||
|
||||
public boolean isField() {
|
||||
return isField;
|
||||
}
|
||||
|
||||
public void setField(boolean field) {
|
||||
isField = field;
|
||||
}
|
||||
|
||||
public ExecutableElement getExecutableElement() {
|
||||
return executableElement;
|
||||
}
|
||||
|
||||
public void setExecutableElement(ExecutableElement executableElement) {
|
||||
this.executableElement = executableElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
package top.niunaijun.blackreflection;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.Filer;
|
||||
import javax.annotation.processing.Messager;
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.annotation.processing.Processor;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.MirroredTypeException;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.Elements;
|
||||
|
||||
import top.niunaijun.blackreflection.annotation.BClass;
|
||||
import top.niunaijun.blackreflection.annotation.BConstructor;
|
||||
import top.niunaijun.blackreflection.annotation.BField;
|
||||
import top.niunaijun.blackreflection.annotation.BMethod;
|
||||
import top.niunaijun.blackreflection.annotation.BStaticField;
|
||||
import top.niunaijun.blackreflection.annotation.BStaticMethod;
|
||||
import top.niunaijun.blackreflection.annotation.BClassName;
|
||||
import top.niunaijun.blackreflection.proxy.BlackReflectionInterfaceProxy;
|
||||
import top.niunaijun.blackreflection.proxy.BlackReflectionProxy;
|
||||
|
||||
|
||||
@AutoService(Processor.class)
|
||||
public class BlackReflectionProcessor extends AbstractProcessor {
|
||||
|
||||
private Map<String, BlackReflectionProxy> mBlackReflectionProxies;
|
||||
private Map<String, BlackReflectionInterfaceProxy> mBlackReflectionInterfaceProxies;
|
||||
private Map<String, String> mRealMaps = new HashMap<>();
|
||||
|
||||
private Messager mMessager;
|
||||
private Elements mElementUtils; //元素相关的辅助类
|
||||
private Filer mFiler;
|
||||
|
||||
@Override
|
||||
public synchronized void init(ProcessingEnvironment processingEnv) {
|
||||
super.init(processingEnv);
|
||||
mMessager = processingEnv.getMessager();
|
||||
mElementUtils = processingEnv.getElementUtils();
|
||||
mFiler = processingEnv.getFiler();
|
||||
mBlackReflectionProxies = new Hashtable<>();
|
||||
mBlackReflectionInterfaceProxies = new Hashtable<>();
|
||||
mRealMaps = new Hashtable<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getSupportedAnnotationTypes() {
|
||||
HashSet<String> supportTypes = new LinkedHashSet<>();
|
||||
supportTypes.add(BClass.class.getCanonicalName());
|
||||
supportTypes.add(BClassName.class.getCanonicalName());
|
||||
|
||||
supportTypes.add(BField.class.getCanonicalName());
|
||||
supportTypes.add(BStaticField.class.getCanonicalName());
|
||||
|
||||
supportTypes.add(BMethod.class.getCanonicalName());
|
||||
supportTypes.add(BStaticMethod.class.getCanonicalName());
|
||||
|
||||
supportTypes.add(BConstructor.class.getCanonicalName());
|
||||
return supportTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceVersion getSupportedSourceVersion() {
|
||||
return SourceVersion.RELEASE_8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
mBlackReflectionProxies.clear();
|
||||
mBlackReflectionInterfaceProxies.clear();
|
||||
mRealMaps.clear();
|
||||
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(BClassName.class)) {
|
||||
BClassName annotation = element.getAnnotation(BClassName.class);
|
||||
doProcess(element, annotation.value());
|
||||
}
|
||||
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(BClass.class)) {
|
||||
BClass annotation = element.getAnnotation(BClass.class);
|
||||
String aClass = getClass(annotation).toString();
|
||||
doProcess(element, aClass);
|
||||
}
|
||||
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(BStaticMethod.class)) {
|
||||
doInterfaceProcess(element, true, false);
|
||||
}
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(BMethod.class)) {
|
||||
doInterfaceProcess(element, false, false);
|
||||
}
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(BStaticField.class)) {
|
||||
doInterfaceProcess(element, true, true);
|
||||
}
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(BField.class)) {
|
||||
doInterfaceProcess(element, false, true);
|
||||
}
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(BConstructor.class)) {
|
||||
doInterfaceProcess(element, true, false);
|
||||
}
|
||||
|
||||
for (BlackReflectionInterfaceProxy value : mBlackReflectionInterfaceProxies.values()) {
|
||||
try {
|
||||
value.setRealMap(mRealMaps);
|
||||
value.generateInterfaceCode().writeTo(mFiler);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
for (BlackReflectionProxy value : mBlackReflectionProxies.values()) {
|
||||
try {
|
||||
value.generateJavaCode().writeTo(mFiler);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void doInterfaceProcess(Element element, boolean isStatic, boolean isField) {
|
||||
String className = element.getEnclosingElement().asType().toString();
|
||||
ExecutableElement executableElement = (ExecutableElement) element;
|
||||
String packageName = mElementUtils.getPackageOf(executableElement).getQualifiedName().toString();
|
||||
|
||||
BlackReflectionInterfaceInfo interfaceInfo = new BlackReflectionInterfaceInfo();
|
||||
interfaceInfo.setExecutableElement(executableElement);
|
||||
interfaceInfo.setField(isField);
|
||||
|
||||
BlackReflectionInterfaceProxy reflectionInterfaceProxy = getReflectionInterfaceProxy(packageName,
|
||||
className + (isStatic ? "Static" : "Context"),
|
||||
className);
|
||||
reflectionInterfaceProxy.add(interfaceInfo);
|
||||
}
|
||||
|
||||
private void doProcess(Element element, String realClassName) {
|
||||
String packageName = mElementUtils.getPackageOf(element).getQualifiedName().toString();
|
||||
String className = element.asType().toString();
|
||||
BlackReflectionInfo info = new BlackReflectionInfo();
|
||||
info.setRealClass(realClassName);
|
||||
info.setClassName(className);
|
||||
|
||||
getReflectionProxy(packageName, className, info);
|
||||
|
||||
// 创建两个基本类
|
||||
getReflectionInterfaceProxy(packageName, className + "Context",
|
||||
className);
|
||||
getReflectionInterfaceProxy(packageName, className + "Static",
|
||||
className);
|
||||
mRealMaps.put(className, realClassName);
|
||||
}
|
||||
|
||||
private static TypeMirror getClass(BClass annotation) {
|
||||
try {
|
||||
annotation.value(); // this should throw
|
||||
} catch (MirroredTypeException mte) {
|
||||
return mte.getTypeMirror();
|
||||
}
|
||||
return null; // can this ever happen ??
|
||||
}
|
||||
|
||||
public BlackReflectionProxy getReflectionProxy(String packageName, String className, BlackReflectionInfo info) {
|
||||
BlackReflectionProxy blackReflectionProxy = mBlackReflectionProxies.get(className);
|
||||
if (blackReflectionProxy == null) {
|
||||
blackReflectionProxy = new BlackReflectionProxy(packageName, info);
|
||||
mBlackReflectionProxies.put(className, blackReflectionProxy);
|
||||
}
|
||||
return blackReflectionProxy;
|
||||
}
|
||||
|
||||
public BlackReflectionInterfaceProxy getReflectionInterfaceProxy(String packageName, String className, String origClassName) {
|
||||
BlackReflectionInterfaceProxy blackReflectionProxy = mBlackReflectionInterfaceProxies.get(className);
|
||||
if (blackReflectionProxy == null) {
|
||||
blackReflectionProxy = new BlackReflectionInterfaceProxy(packageName, className, origClassName);
|
||||
mBlackReflectionInterfaceProxies.put(className, blackReflectionProxy);
|
||||
}
|
||||
return blackReflectionProxy;
|
||||
}
|
||||
}
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
package top.niunaijun.blackreflection.proxy;
|
||||
|
||||
import com.squareup.javapoet.AnnotationSpec;
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.JavaFile;
|
||||
import com.squareup.javapoet.MethodSpec;
|
||||
import com.squareup.javapoet.ParameterSpec;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.MirroredTypeException;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
|
||||
import top.niunaijun.blackreflection.BlackReflectionInterfaceInfo;
|
||||
import top.niunaijun.blackreflection.annotation.BConstructor;
|
||||
import top.niunaijun.blackreflection.annotation.BConstructorNotProcess;
|
||||
import top.niunaijun.blackreflection.annotation.BFieldCheckNotProcess;
|
||||
import top.niunaijun.blackreflection.annotation.BFieldNotProcess;
|
||||
import top.niunaijun.blackreflection.annotation.BFieldSetNotProcess;
|
||||
import top.niunaijun.blackreflection.annotation.BMethodCheckNotProcess;
|
||||
import top.niunaijun.blackreflection.annotation.BParamClass;
|
||||
import top.niunaijun.blackreflection.annotation.BClassNameNotProcess;
|
||||
import top.niunaijun.blackreflection.annotation.BParamClassName;
|
||||
|
||||
/**
|
||||
* Created by sunwanquan on 2020/1/8.
|
||||
* * ∧_∧
|
||||
* (`・ω・∥
|
||||
* 丶 つ0
|
||||
* しーJ
|
||||
* 此处无Bug
|
||||
*/
|
||||
public class BlackReflectionInterfaceProxy {
|
||||
|
||||
private final List<BlackReflectionInterfaceInfo> mReflections = new ArrayList<>();
|
||||
// fake.android.app.ActivityThreadStatic or ActivityThreadContext
|
||||
private final String mClassName;
|
||||
// fake.android.app
|
||||
private final String mPackageName;
|
||||
// fake.android.app.ActivityThread
|
||||
private final String mOrigClassName;
|
||||
private Map<String, String> realMaps;
|
||||
|
||||
public BlackReflectionInterfaceProxy(String packageName, String className, String origClassName) {
|
||||
mPackageName = packageName;
|
||||
mClassName = className;
|
||||
mOrigClassName = origClassName;
|
||||
}
|
||||
|
||||
public JavaFile generateInterfaceCode() {
|
||||
String finalClass = mClassName
|
||||
.replace(mPackageName + ".", "")
|
||||
.replace(".", "");
|
||||
AnnotationSpec annotationSpec = AnnotationSpec.builder(BClassNameNotProcess.class)
|
||||
.addMember("value","$S", realMaps.get(mOrigClassName))
|
||||
.build();
|
||||
|
||||
// generaClass
|
||||
TypeSpec.Builder interfaceBuilder = TypeSpec.interfaceBuilder(finalClass)
|
||||
.addAnnotation(annotationSpec)
|
||||
.addModifiers(Modifier.PUBLIC);
|
||||
|
||||
for (BlackReflectionInterfaceInfo reflection : mReflections) {
|
||||
MethodSpec.Builder method = MethodSpec.methodBuilder(reflection.getExecutableElement().getSimpleName().toString())
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT);
|
||||
|
||||
List<ParameterSpec> parameterSpecs = new ArrayList<>();
|
||||
for (VariableElement typeParameter : reflection.getExecutableElement().getParameters()) {
|
||||
ParameterSpec.Builder builder = ParameterSpec.builder(ClassName.get(typeParameter.asType()), typeParameter.getSimpleName().toString());
|
||||
if (typeParameter.getAnnotation(BParamClassName.class) != null) {
|
||||
BParamClassName annotation = typeParameter.getAnnotation(BParamClassName.class);
|
||||
builder.addAnnotation(AnnotationSpec.get(annotation));
|
||||
}
|
||||
if (typeParameter.getAnnotation(BParamClass.class) != null) {
|
||||
BParamClass annotation = typeParameter.getAnnotation(BParamClass.class);
|
||||
String annotationValue = getClass(annotation).toString();
|
||||
Class<?> aClass = parseBaseClass(annotationValue);
|
||||
if (aClass != null) {
|
||||
builder.addAnnotation(AnnotationSpec.builder(BParamClass.class)
|
||||
.addMember("value", "$T.class", aClass).build());
|
||||
} else {
|
||||
builder.addAnnotation(AnnotationSpec.builder(BParamClass.class)
|
||||
.addMember("value", annotationValue + ".class").build());
|
||||
}
|
||||
}
|
||||
|
||||
ParameterSpec build = builder.build();
|
||||
parameterSpecs.add(build);
|
||||
method.addParameter(build);
|
||||
}
|
||||
TypeName typeName = TypeName.get(reflection.getExecutableElement().getReturnType());
|
||||
method.returns(typeName.box());
|
||||
if (reflection.isField()) {
|
||||
method.addAnnotation(AnnotationSpec.builder(BFieldNotProcess.class).build());
|
||||
// set field
|
||||
interfaceBuilder.addMethod(generateFieldSet(reflection));
|
||||
// check field
|
||||
interfaceBuilder.addMethod(generateFieldCheck(reflection));
|
||||
} else {
|
||||
BConstructor annotation = reflection.getExecutableElement().getAnnotation(BConstructor.class);
|
||||
if (annotation != null) {
|
||||
method.addAnnotation(AnnotationSpec.builder(BConstructorNotProcess.class).build());
|
||||
} else {
|
||||
// check method
|
||||
interfaceBuilder.addMethod(generateMethodCheck(reflection, parameterSpecs));
|
||||
}
|
||||
}
|
||||
interfaceBuilder.addMethod(method.build());
|
||||
}
|
||||
return JavaFile.builder(mPackageName, interfaceBuilder.build()).build();
|
||||
}
|
||||
|
||||
private MethodSpec generateFieldSet(BlackReflectionInterfaceInfo reflection) {
|
||||
MethodSpec.Builder method = MethodSpec.methodBuilder("_set_" + reflection.getExecutableElement().getSimpleName().toString())
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
||||
.addParameter(ClassName.get("java.lang", "Object"), "value", Modifier.FINAL)
|
||||
.addAnnotation(AnnotationSpec.builder(BFieldSetNotProcess.class).build());
|
||||
return method.build();
|
||||
}
|
||||
|
||||
private MethodSpec generateFieldCheck(BlackReflectionInterfaceInfo reflection) {
|
||||
MethodSpec.Builder method = MethodSpec.methodBuilder("_check_" + reflection.getExecutableElement().getSimpleName().toString())
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
||||
.addAnnotation(AnnotationSpec.builder(BFieldCheckNotProcess.class).build())
|
||||
.returns(Field.class);
|
||||
return method.build();
|
||||
}
|
||||
|
||||
private MethodSpec generateMethodCheck(BlackReflectionInterfaceInfo reflection, List<ParameterSpec> parameterSpecs) {
|
||||
MethodSpec.Builder method = MethodSpec.methodBuilder("_check_" + reflection.getExecutableElement().getSimpleName().toString())
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT)
|
||||
.addAnnotation(AnnotationSpec.builder(BMethodCheckNotProcess.class).build())
|
||||
.returns(Method.class);
|
||||
for (ParameterSpec parameterSpec : parameterSpecs) {
|
||||
method.addParameter(parameterSpec);
|
||||
}
|
||||
return method.build();
|
||||
}
|
||||
|
||||
public void add(BlackReflectionInterfaceInfo interfaceInfo) {
|
||||
mReflections.add(interfaceInfo);
|
||||
}
|
||||
|
||||
public void setRealMap(Map<String, String> realMaps) {
|
||||
this.realMaps = realMaps;
|
||||
}
|
||||
|
||||
private static TypeMirror getClass(BParamClass annotation) {
|
||||
try {
|
||||
annotation.value(); // this should throw
|
||||
} catch (MirroredTypeException mte) {
|
||||
return mte.getTypeMirror();
|
||||
}
|
||||
return null; // can this ever happen ??
|
||||
}
|
||||
|
||||
private static Class<?> parseBaseClass(String className) {
|
||||
switch (className) {
|
||||
case "int":
|
||||
return int.class;
|
||||
case "byte":
|
||||
return byte.class;
|
||||
case "short":
|
||||
return short.class;
|
||||
case "long":
|
||||
return long.class;
|
||||
case "float":
|
||||
return float.class;
|
||||
case "double":
|
||||
return double.class;
|
||||
case "boolean":
|
||||
return boolean.class;
|
||||
case "char":
|
||||
return char.class;
|
||||
case "int[]":
|
||||
return int[].class;
|
||||
case "byte[]":
|
||||
return byte[].class;
|
||||
case "short[]":
|
||||
return short[].class;
|
||||
case "long[]":
|
||||
return long[].class;
|
||||
case "float[]":
|
||||
return float[].class;
|
||||
case "double[]":
|
||||
return double[].class;
|
||||
case "boolean[]":
|
||||
return boolean[].class;
|
||||
case "char[]":
|
||||
return char[].class;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package top.niunaijun.blackreflection.proxy;
|
||||
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.JavaFile;
|
||||
import com.squareup.javapoet.MethodSpec;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
|
||||
import javax.lang.model.element.Modifier;
|
||||
|
||||
import top.niunaijun.blackreflection.BlackReflectionInfo;
|
||||
import top.niunaijun.blackreflection.utils.ClassUtils;
|
||||
|
||||
/**
|
||||
* Created by sunwanquan on 2020/1/8.
|
||||
* * ∧_∧
|
||||
* (`・ω・∥
|
||||
* 丶 つ0
|
||||
* しーJ
|
||||
* 此处无Bug
|
||||
*/
|
||||
public class BlackReflectionProxy {
|
||||
|
||||
private static final ClassName BR = ClassName.get("top.niunaijun.blackreflection", "BlackReflection");
|
||||
private final BlackReflectionInfo mReflection;
|
||||
|
||||
private final ClassName mContextInterface;
|
||||
private final ClassName mStaticInterface;
|
||||
private final String mPackageName;
|
||||
|
||||
public BlackReflectionProxy(String packageName, BlackReflectionInfo reflection) {
|
||||
mReflection = reflection;
|
||||
mPackageName = packageName;
|
||||
String finalClass = mReflection.getClassName()
|
||||
.replace(packageName + ".", "")
|
||||
.replace(".", "");
|
||||
|
||||
mContextInterface = ClassName.get(ClassUtils.getPackage(finalClass), ClassUtils.getName(finalClass + "Context"));
|
||||
mStaticInterface = ClassName.get(ClassUtils.getPackage(finalClass), ClassUtils.getName(finalClass + "Static"));
|
||||
}
|
||||
|
||||
public JavaFile generateJavaCode() {
|
||||
String finalClass = "BR" + mReflection.getClassName()
|
||||
.replace(mPackageName + ".", "")
|
||||
.replace(".", "");
|
||||
|
||||
// generaClass
|
||||
TypeSpec reflection = TypeSpec.classBuilder(finalClass)
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.addMethod(generaNotCallerMethod(true))
|
||||
.addMethod(generaNotCallerMethod(false))
|
||||
.addMethod(generaCallerMethod(true))
|
||||
.addMethod(generaCallerMethod(false))
|
||||
.addMethod(generaIsLoadMethod())
|
||||
.build();
|
||||
return JavaFile.builder(mPackageName, reflection).build();
|
||||
}
|
||||
|
||||
private MethodSpec generaNotCallerMethod(boolean withException) {
|
||||
MethodSpec.Builder builder = MethodSpec.methodBuilder("get" + (withException ? "WithException" : ""))
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||
.returns(mStaticInterface);
|
||||
String statement = "return $T.create($T.class, null, $L)";
|
||||
builder.addStatement(statement,
|
||||
BR,
|
||||
mStaticInterface,
|
||||
withException
|
||||
);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private MethodSpec generaCallerMethod(boolean withException) {
|
||||
MethodSpec.Builder builder = MethodSpec.methodBuilder("get" + (withException ? "WithException" : ""))
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||
.addParameter(ClassName.get("java.lang", "Object"), "caller", Modifier.FINAL)
|
||||
.returns(mContextInterface);
|
||||
|
||||
String statement = "return $T.create($T.class, caller, $L)";
|
||||
builder.addStatement(statement,
|
||||
BR,
|
||||
mContextInterface,
|
||||
withException
|
||||
);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private MethodSpec generaIsLoadMethod() {
|
||||
MethodSpec.Builder builder = MethodSpec.methodBuilder("getRealClass")
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
|
||||
.returns(ClassName.get(Class.class));
|
||||
|
||||
String statement = "return top.niunaijun.blackreflection.utils.ClassUtil.classReady($T.class)";
|
||||
builder.addStatement(statement,
|
||||
mContextInterface
|
||||
);
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package top.niunaijun.blackreflection.utils;
|
||||
|
||||
|
||||
/**
|
||||
* Created by sunwanquan on 2020/1/8.
|
||||
* * ∧_∧
|
||||
* (`・ω・∥
|
||||
* 丶 つ0
|
||||
* しーJ
|
||||
* 此处无Bug
|
||||
*/
|
||||
public class ClassUtils {
|
||||
|
||||
public static String getPackage(String className) {
|
||||
String[] sp = className.split("[.]");
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < sp.length - 1; i++) {
|
||||
builder.append(sp[i]);
|
||||
if (i != sp.length - 2) {
|
||||
builder.append(".");
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static String getName(String className) {
|
||||
String[] sp = className.split("[.]");
|
||||
return sp[sp.length - 1];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user