package com.limpoxe.fairy.util; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @SuppressWarnings("unchecked") public class RefInvoker { private static final ClassLoader system = ClassLoader.getSystemClassLoader(); private static final ClassLoader bootloader = system.getParent(); private static final ClassLoader application = RefInvoker.class.getClassLoader(); private static HashMap<String, Class> clazzCache = new HashMap<String, Class>(); public static Class forName(String clazzName) throws ClassNotFoundException { Class clazz = clazzCache.get(clazzName); if (clazz == null) { clazz = Class.forName(clazzName); ClassLoader cl = clazz.getClassLoader(); if (cl == system || cl == application || cl == bootloader) { clazzCache.put(clazzName, clazz); } } return clazz; } public static Object newInstance(String className, Class[] paramTypes, Object[] paramValues) { try { Class clazz = forName(className); Constructor constructor = clazz.getConstructor(paramTypes); if (!constructor.isAccessible()) { constructor.setAccessible(true); } return constructor.newInstance(paramValues); } catch (ClassNotFoundException e) { e.printStackTrace(); LogUtil.printException("ClassNotFoundException", e); } catch (NoSuchMethodException e) { e.printStackTrace(); LogUtil.printException("NoSuchMethodException", e); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } public static Object invokeMethod(Object target, String className, String methodName, Class[] paramTypes, Object[] paramValues) { try { Class clazz = forName(className); return invokeMethod(target, clazz, methodName, paramTypes, paramValues); }catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } public static Object invokeMethod(Object target, Class clazz, String methodName, Class[] paramTypes, Object[] paramValues) { try { Method method = clazz.getDeclaredMethod(methodName, paramTypes); if (!method.isAccessible()) { method.setAccessible(true); } return method.invoke(target, paramValues); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } @SuppressWarnings("rawtypes") public static Object getField(Object target, String className, String fieldName) { try { Class clazz = forName(className); return getField(target, clazz, fieldName); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } @SuppressWarnings("rawtypes") public static Object getField(Object target, Class clazz, String fieldName) { try { Field field = clazz.getDeclaredField(fieldName); if (!field.isAccessible()) { field.setAccessible(true); } return field.get(target); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { // try supper for Miui, Miui has a class named MiuiPhoneWindow try { Field field = clazz.getSuperclass().getDeclaredField(fieldName); field.setAccessible(true); return field.get(target); } catch (Exception superE) { e.printStackTrace(); superE.printStackTrace(); } } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } @SuppressWarnings("rawtypes") public static void setField(Object target, String className, String fieldName, Object fieldValue) { try { Class clazz = forName(className); setField(target, clazz, fieldName, fieldValue); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static void setField(Object target, Class clazz, String fieldName, Object fieldValue) { try { Field field = clazz.getDeclaredField(fieldName); if (!field.isAccessible()) { field.setAccessible(true); } field.set(target, fieldValue); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { // try supper for Miui, Miui has a class named MiuiPhoneWindow try { Field field = clazz.getSuperclass().getDeclaredField(fieldName); if (!field.isAccessible()) { field.setAccessible(true); } field.set(target, fieldValue); } catch (Exception superE) { e.printStackTrace(); //superE.printStackTrace(); } } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } public static Method findMethod(Object object, String methodName, Class[] clazzes) { try { return object.getClass().getDeclaredMethod(methodName, clazzes); } catch (NoSuchMethodException e) { e.printStackTrace(); } return null; } public static Method findMethod(Object object, String methodName, Object[] args) { if (args == null) { try { return object.getClass().getDeclaredMethod(methodName, (Class[])null); } catch (NoSuchMethodException e) { e.printStackTrace(); } return null; } else { Method[] methods = object.getClass().getDeclaredMethods(); boolean isFound = false; Method method = null; for(Method m: methods) { if (m.getName().equals(methodName)) { Class<?>[] types = m.getParameterTypes(); if (types.length == args.length) { isFound = true; for(int i = 0; i < args.length; i++) { if (!(types[i] == args[i].getClass() || (types[i].isPrimitive() && primitiveToWrapper(types[i]) == args[i].getClass()))) { isFound = false; break; } } if (isFound) { method = m; break; } } } } return method; } } private static final Map<Class<?>, Class<?>> primitiveWrapperMap = new HashMap<Class<?>, Class<?>>(); static { primitiveWrapperMap.put(Boolean.TYPE, Boolean.class); primitiveWrapperMap.put(Byte.TYPE, Byte.class); primitiveWrapperMap.put(Character.TYPE, Character.class); primitiveWrapperMap.put(Short.TYPE, Short.class); primitiveWrapperMap.put(Integer.TYPE, Integer.class); primitiveWrapperMap.put(Long.TYPE, Long.class); primitiveWrapperMap.put(Double.TYPE, Double.class); primitiveWrapperMap.put(Float.TYPE, Float.class); primitiveWrapperMap.put(Void.TYPE, Void.TYPE); } static Class<?> primitiveToWrapper(final Class<?> cls) { Class<?> convertedClass = cls; if (cls != null && cls.isPrimitive()) { convertedClass = primitiveWrapperMap.get(cls); } return convertedClass; } public static ArrayList dumpAllInfo(String className) { try { Class clazz = Class.forName(className); return dumpAllInfo(clazz); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } public static ArrayList dumpAllInfo(Class clazz) { ArrayList arrayList = new ArrayList(); LogUtil.i("clazz=" + clazz.getName()); LogUtil.i("Superclass=" + clazz.getSuperclass()); Constructor[] ctors = clazz.getDeclaredConstructors(); if (ctors != null) { LogUtil.w("DeclaredConstructors--------------------" + ctors.length); for(Constructor c : ctors){ LogUtil.i(c); arrayList.add(c); } } Constructor[] publicCtors = clazz.getConstructors(); if (publicCtors != null) { LogUtil.w("Constructors-------------------------" + publicCtors.length); for(Constructor c :publicCtors){ LogUtil.i(c); arrayList.add(c); } } Method[] mtds = clazz.getDeclaredMethods(); if (mtds != null) { LogUtil.w("DeclaredMethods-------------------------" + mtds.length); for(Method m : mtds){ LogUtil.i(m); arrayList.add(m); } } Method[] mts = clazz.getMethods(); if (mts != null) { LogUtil.w("Methods-------------------------" + mts.length); for(Method m : mts){ LogUtil.i(m); arrayList.add(m); } } Class<?>[] inners = clazz.getDeclaredClasses(); if (inners != null) { LogUtil.w("DeclaredClasses-------------------------" + inners.length); for(Class c : inners){ LogUtil.i(c.getName()); arrayList.add(c.getName()); } } Class<?>[] classes = clazz.getClasses(); if (classes != null) { LogUtil.w("classes-------------------------" + classes.length); for(Class c : classes){ LogUtil.i(c.getName()); arrayList.add(c.getName()); } } Field[] dfields = clazz.getDeclaredFields(); if (dfields != null) { LogUtil.w("DeclaredFields-------------------------" + dfields.length); for(Field f : dfields){ LogUtil.i(f); arrayList.add(f); } } Field[] fields = clazz.getFields(); if (fields != null) { LogUtil.w("Fields-------------------------" + fields.length); for(Field f : fields){ LogUtil.i(f); arrayList.add(f); } } Annotation[] anns = clazz.getAnnotations(); if (anns != null) { LogUtil.w("Annotations-------------------------" + anns.length); for(Annotation an : anns){ LogUtil.i(an); arrayList.add(an); } } return arrayList; } public static ArrayList dumpAllInfo(Object object) { Class clazz = object.getClass(); return dumpAllInfo(clazz); } }