我正在尝试实现一个包扫描功能,类似于 Spring 的component-scan
,对于我正在开发的Android框架。基本上,我希望能够指定一个基础包,例如com.foo.bar
并检索所有Class
具有特定注释的实例。我不想在我的框架中注册每个组件,因为这会破坏自动扫描的目的。
根据我的研究,Java 似乎不可能使用反射来检索给定包名称的资源。不过,我简单地研究了一下思考框架,我想知道是否有 Android 兼容的等效项。如果没有,也许有一种不太明显的方法来完成我想做的事情。
我稍微研究了一下 Spring 源代码,看看他们是如何实现这一目标的,但我不认为他们正在做的事情会在 Dalvik 运行时中起作用。
Update
目前,下面的代码是我能检索包含特定注释的所有类的最佳方法,但坦率地说,这是一个非常糟糕的解决方案。它做出了一些非常不安全的假设ClassLoader
另外,它还会扫描(并加载)所有应用程序类。
public Set<Class<?>> getClassesWithAnnotation(Class<? extends Annotation> annotation) {
Set<Class<?>> classes = new HashSet<Class<?>>();
Field dexField = PathClassLoader.class.getDeclaredField("mDexs");
dexField.setAccessible(true);
PathClassLoader classLoader = (PathClassLoader) Thread.currentThread().getContextClassLoader();
DexFile[] dexs = (DexFile[]) dexField.get(classLoader);
for (DexFile dex : dexs) {
Enumeration<String> entries = dex.entries();
while (entries.hasMoreElements()) {
String entry = entries.nextElement();
Class<?> entryClass = dex.loadClass(entry, classLoader);
if (entryClass != null && entryClass.isAnnotationPresent(annotation)) {
classes.add(entryClass);
}
}
}
return classes;
}
我想在运行时找到所有子类。
所以我一直在寻找android类扫描。
这是我在网络上收集的最终代码。
你会明白的。
public static void findSubClasses(Context context, Class parent) {
ApplicationInfo ai = context.getApplicationInfo();
String classPath = ai.sourceDir;
DexFile dex = null;
try {
dex = new DexFile(classPath);
Enumeration<String> apkClassNames = dex.entries();
while (apkClassNames.hasMoreElements()) {
String className = apkClassNames.nextElement();
try {
Class c = context.getClassLoader().loadClass(className);
if (parent.isAssignableFrom(c)) {
android.util.Log.i("nora", className);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// android.util.Log.i("nora", className);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
dex.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)