Создайте пользовательскую аннотацию Java для изменения метода
Я хочу создать аннотацию, чтобы весной сделать метод асинхронным, как @Async, но для Android. Я проверил процессор аннотаций Java, но он не позволяет изменять существующий класс (мы можем только создать новый класс). Я не хочу использовать библиотеку androidannotation, потому что я также хочу научиться создавать свои собственные аннотации
Я видел, что lombok позволяет изменять класс (добавлять методы получения и установки), и мы можем добавлять собственные аннотации ( https://binkley.blogspot.fr/2014/12/writing-your-own-lombok-annotation.html).
Но у меня проблемы с модификацией этого примера, чтобы создать асинхронную задачу и ввести код метода.
Спасибо за помощь
@AsyncTask
void doSomething(int a){
Log.d("here");
}
->
void doSomething(int a){
new android.os.AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground( Void... voids ) {
Log.d("here");
return null;
}
}.execute();
}
1 ответ
Сначала мы определяем аннотацию:
@Documented
@Retention(RUNTIME)
@Target(METHOD)
public @interface AsyncTask {
}
Тогда мы используем cglib
создать асинхронную логику для @AsyncTask
метод:
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
public class AsyncTaskHandler {
@SuppressWarnings("unchecked")
public static <T> T handle(T origin) {
// collect async methods
List<Method> asyncMethods = Arrays.stream(origin.getClass().getMethods())
.filter(m -> m.getAnnotation(AsyncTask.class) != null)
.collect(Collectors.toList());
// if no async method, return itself
if (asyncMethods.isEmpty()) {
return origin;
}
return (T) Enhancer.create(origin.getClass(), (MethodInterceptor) (obj, method, args, proxy) -> {
// if asyn, wrapped in your async code, here I simply create a new thread
if (asyncMethods.contains(method)) {
// your async logic
new Thread(() -> {
try {
proxy.invoke(origin, args);
} catch (Throwable e) {
e.printStackTrace();
}
}).start();
return null;
}
return proxy.invoke(origin, args);
});
}
}
Давайте проверим наш код.
public class SomeObject {
public static void main(String[] args) {
SomeObject so = SomeObject.create();
so.syncDo("1");
so.asyncDo("2");
so.syncDo("3");
so.asyncDo("4");
}
public static SomeObject create() {
return AsyncTaskHandler.handle(new SomeObject());
}
protected SomeObject() {}
@AsyncTask
public void asyncDo(String who) {
System.out.println(who + "\tThread: " + Thread.currentThread());
}
public void syncDo(String who) {
System.out.println(who + "\tThread: " + Thread.currentThread());
}
}
и вывод:
1 Thread: Thread[main,5,main]
3 Thread: Thread[main,5,main]
2 Thread: Thread[Thread-0,5,main]
5 Thread: Thread[Thread-1,5,main]