package com.evernote.client.android; import android.os.Handler; import android.os.Looper; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Class that uses reflection to asynchronously wrap Client methods */ class AsyncReflector { /** * List of primitives to convert from autoboxed method calls */ public final static Map<Class<?>, Class<?>> PRIMITIVE_MAP = new HashMap<Class<?>, Class<?>>(); static { PRIMITIVE_MAP.put(Boolean.class, boolean.class); PRIMITIVE_MAP.put(Byte.class, byte.class); PRIMITIVE_MAP.put(Short.class, short.class); PRIMITIVE_MAP.put(Character.class, char.class); PRIMITIVE_MAP.put(Integer.class, int.class); PRIMITIVE_MAP.put(Long.class, long.class); PRIMITIVE_MAP.put(Float.class, float.class); PRIMITIVE_MAP.put(Double.class, double.class); } /** * Singled threaded Executor for async work */ private static ExecutorService sThreadExecutor = Executors.newSingleThreadExecutor(); /** * Reflection to run Asynchronous methods */ static <T> void execute(final Object receiver, final OnClientCallback<T> callback, final String function, final Object... args) { final Handler handler = new Handler(Looper.getMainLooper()); sThreadExecutor.execute(new Runnable() { public void run() { try { Class[] classes = new Class[args.length]; for (int i = 0; i < args.length; i++) { //Convert Autoboxed primitives to actual primitives (ex: Integer.class to int.class) if(PRIMITIVE_MAP.containsKey(args[i].getClass())) { classes[i] = PRIMITIVE_MAP.get(args[i].getClass()); } else { classes[i] = args[i].getClass(); } } Method method = null; if(receiver instanceof Class) { //Can receive a class if using for static methods method = ((Class)receiver).getMethod(function, classes); } else { //used for instance methods method = receiver.getClass().getMethod(function, classes); } final T answer = (T) method.invoke(receiver, args); handler.post(new Runnable() { @Override public void run() { if(callback != null) callback.onSuccess(answer); } }); } catch (final Exception ex) { handler.post(new Runnable() { @Override public void run() { if(callback != null) callback.onException(ex); } }); } } }); } }