Skip to content

Commit

Permalink
supported set field and getWithException
Browse files Browse the repository at this point in the history
  • Loading branch information
nnjun committed Feb 16, 2022
1 parent 97a0a80 commit 854865c
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 41 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ public interface ActivityThread {
int CREATE_SERVICE();
}
}
}
```
#### 2. build一次,让我生成相关的代码。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@

import top.niunaijun.blackreflection.ref.BRActivityThread;
import top.niunaijun.blackreflection.ref.BRActivityThreadH;
import top.niunaijun.blackreflection.ref.BRMainActivity;


public class MainActivity extends AppCompatActivity {
public static final String TAG = "MainActivity";

public static String TAGStatic = "tag static";
public String TAGContext = "tag context";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand All @@ -22,13 +27,29 @@ protected void onCreate(Bundle savedInstanceState) {
startActivity(intent);
});


// call method
Object currentActivityThread = BRActivityThread.get().currentActivityThread();
String processName = BRActivityThread.get(currentActivityThread).getProcessName();
Log.d(TAG, "processName: " + processName);


// get field
int CREATE_SERVICE = BRActivityThreadH.get().CREATE_SERVICE();
Log.d(TAG, "field CREATE_SERVICE: " + CREATE_SERVICE);
Log.d(TAG, "get field CREATE_SERVICE: " + CREATE_SERVICE);


// set field
Log.d(TAG, "before set TAGStatic: " + TAGStatic);
BRMainActivity.get().setTAGStatic(TAGStatic + " changed");
Log.d(TAG, "after set TAGStatic: " + TAGStatic);

Log.d(TAG, "before set TAGContext: " + TAGContext);
BRMainActivity.get(this).setTAGContext(TAGContext + " changed");
Log.d(TAG, "after set TAGContext: " + TAGContext);
}

public void test() {
throw new RuntimeException("test RuntimeException");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
public class SecondActivity extends AppCompatActivity {

@Override
protected void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

SecondActivity activity = SecondActivity.this;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package top.niunaijun.blackreflection.ref;

import top.niunaijun.blackreflection.annotation.BClass;
import top.niunaijun.blackreflection.annotation.BField;
import top.niunaijun.blackreflection.annotation.BMethod;
import top.niunaijun.blackreflection.annotation.BStaticField;

/**
* Created by Milk on 2022/2/16.
* * ∧_∧
* (`・ω・∥
* 丶 つ0
* しーJ
* 此处无Bug
*/
@BClass(top.niunaijun.blackreflection.MainActivity.class)
public interface MainActivity {
@BStaticField
String TAGStatic();

@BField
String TAGContext();

@BMethod
void test();
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@

import top.niunaijun.blackreflection.BlackReflectionInterfaceInfo;
import top.niunaijun.blackreflection.annotation.BFieldNotProcess;
import top.niunaijun.blackreflection.annotation.BFieldSetNotProcess;
import top.niunaijun.blackreflection.annotation.BParamClass;
import top.niunaijun.blackreflection.annotation.BStrClassNotProcess;
import top.niunaijun.blackreflection.annotation.BStrParamClass;
import top.niunaijun.blackreflection.utils.ClassUtils;

/**
* Created by sunwanquan on 2020/1/8.
Expand Down Expand Up @@ -85,17 +87,24 @@ public JavaFile generateInterfaceCode() {
}
method.addParameter(builder.build());
}
// String returnClass = reflection.getExecutableElement().getReturnType().toString();
method.returns(TypeName.get(reflection.getExecutableElement().getReturnType()));
if (reflection.isField()) {
method.addAnnotation(AnnotationSpec.builder(BFieldNotProcess.class).build());
interfaceBuilder.addMethod(generateFieldSet(reflection));
}
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();
}

public void add(BlackReflectionInterfaceInfo interfaceInfo) {
mReflections.add(interfaceInfo);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package top.niunaijun.blackreflection.proxy;

import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;

import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;
import javax.lang.model.util.Elements;

import top.niunaijun.blackreflection.BlackReflectionInfo;
import top.niunaijun.blackreflection.utils.ClassUtils;
Expand Down Expand Up @@ -42,43 +39,46 @@ public BlackReflectionProxy(String packageName, BlackReflectionInfo reflection)
}

public JavaFile generateJavaCode() {
MethodSpec.Builder getStaticInterface = MethodSpec.methodBuilder("get")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(mStaticInterface);

MethodSpec.Builder getContextInterface = MethodSpec.methodBuilder("get")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.addParameter(ClassName.get("java.lang", "Object"), "caller", Modifier.FINAL)
.returns(mContextInterface);
generaNotCallerMethod(getStaticInterface);
generaCallerMethod(getContextInterface, mReflection);

String finalClass = "BR" + mReflection.getClassName()
.replace(mPackageName + ".", "")
.replace(".", "");

// generaClass
TypeSpec reflection = TypeSpec.classBuilder(finalClass)
.addModifiers(Modifier.PUBLIC)
.addMethod(getStaticInterface.build())
.addMethod(getContextInterface.build())
.addMethod(generaNotCallerMethod(true))
.addMethod(generaNotCallerMethod(false))
.addMethod(generaCallerMethod(true))
.addMethod(generaCallerMethod(false))
.build();
return JavaFile.builder(mPackageName, reflection).build();
}

private void generaNotCallerMethod(MethodSpec.Builder registerMethod) {
String statement = "return $T.create($T.class, null)";
registerMethod.addStatement(statement,
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, $L)";
builder.addStatement(statement,
BR,
mStaticInterface
mStaticInterface,
withException
);
return builder.build();
}

private void generaCallerMethod(MethodSpec.Builder registerMethod, BlackReflectionInfo reflectionInfo) {
String statement = "return $T.create($T.class, caller)";
registerMethod.addStatement(statement,
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
mContextInterface,
withException
);
return builder.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import top.niunaijun.blackreflection.annotation.BClass;
import top.niunaijun.blackreflection.annotation.BField;
import top.niunaijun.blackreflection.annotation.BFieldNotProcess;
import top.niunaijun.blackreflection.annotation.BFieldSetNotProcess;
import top.niunaijun.blackreflection.annotation.BParamClass;
import top.niunaijun.blackreflection.annotation.BStrClass;
import top.niunaijun.blackreflection.annotation.BStrClassNotProcess;
Expand All @@ -33,24 +34,26 @@ public class BlackReflection {
// key caller
private static final WeakHashMap<Object, Map<Class<?>, Object>> sCallerProxyCache = new WeakHashMap<>();

public static <T> T create(Class<T> clazz) {
return create(clazz, null);
public static <T> T create(Class<T> clazz, final Object caller) {
return create(clazz, caller, false);
}

public static <T> T create(Class<T> clazz, final Object caller) {
public static <T> T create(Class<T> clazz, final Object caller, boolean withException) {
try {
if (caller == null) {
Object o = sProxyCache.get(clazz);
if (o != null) {
return (T) o;
}
} else {
Map<Class<?>, Object> callerClassMap = sCallerProxyCache.get(caller);
if (callerClassMap != null) {
Object o = callerClassMap.get(clazz);
if (!withException) {
if (caller == null) {
Object o = sProxyCache.get(clazz);
if (o != null) {
return (T) o;
}
} else {
Map<Class<?>, Object> callerClassMap = sCallerProxyCache.get(caller);
if (callerClassMap != null) {
Object o = callerClassMap.get(clazz);
if (o != null) {
return (T) o;
}
}
}
}

Expand Down Expand Up @@ -82,6 +85,21 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
}
return call;
}
BFieldSetNotProcess bFieldSetNotProcess = method.getAnnotation(BFieldSetNotProcess.class);
if (bFieldSetNotProcess != null) {
// startsWith "set"
name = name.substring(3);
Reflector on = Reflector.on(aClass).field(name);
if (isStatic) {
on.set(args[0]);
} else {
if (callerByWeak == null) {
return 0;
}
on.set(callerByWeak, args[0]);
}
return 0;
}

// method
Class<?>[] paramClass = getParamClass(method);
Expand All @@ -98,6 +116,9 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
return call;
} catch (Throwable throwable) {
throwable.printStackTrace();
if (withException) {
throw throwable;
}
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package top.niunaijun.blackreflection.annotation;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
* Created by Milk on 2022/2/15.
* * ∧_∧
* (`・ω・∥
* 丶 つ0
* しーJ
* 此处无Bug
*/
@Retention(RUNTIME)
@Target({METHOD})
public @interface BFieldSetNotProcess {
}

0 comments on commit 854865c

Please sign in to comment.