首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Android中实现类Spring包扫描

在Android中实现类Spring包扫描
EN

Stack Overflow用户
提问于 2012-07-10 20:06:21
回答 5查看 3.1K关注 0票数 4

我正在尝试为我正在开发的安卓框架实现一个包扫描功能,类似于Spring的component-scan。基本上,我希望能够指定一个基本包,例如com.foo.bar,并检索所有具有特定注释的Class实例。我不想把每个组件都注册到我的框架中,因为这会破坏自动扫描的目的。

根据我的研究,Java似乎不可能使用反射检索给定包名的资源。然而,我简要地看了一下反射框架,我想知道是否有一个与Android兼容的版本。如果没有,也许有一种稍微不那么明显的方式来完成我想做的事情。

我稍微看了一下Spring源代码,看看他们是如何做到这一点的,但我不认为他们正在做的事情在Dalvik运行时中会起作用。

更新

目前,下面的代码是检索所有包含特定注释的类的最好方法,但坦率地说,这是一个非常糟糕的解决方案。它对ClassLoader做了一些非常不安全的假设,加上它扫描(并加载)所有应用程序类。

代码语言:javascript
复制
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;
}
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-07-13 06:42:13

我同意乔普·埃根的观点,认为他的做法很好。在Android系统中,我尽量避免使用通常的web应用程序功能,这会导致一个持久的应用程序启动。我不使用反射或包扫描。

但如果你想..。如果我正确地理解了它,那么您希望有一个类的注释。与使用注释不同,您还可以使用标记接口(只需要更多的可能性)。

1)看

2) AndroidAnnotations

我更喜欢AndroidAnnotations的工作方式(也许AndroidAnnotations中的集成是更好的方法):它会自动添加一个额外的编译步骤来生成源代码,使用标准的AndroidAnnotations处理工具。因此,您可以根据编译期间生成的注释执行代码,而不是运行时扫描。

我认为Bean/EBean注释可以适用于您(只有一个类):https://github.com/excilys/androidannotations/wiki/Enhance%20custom%20classes

扫描功能不可用,请参阅此线程

3)编写自己的注释处理器

  • 注释处理工具。其想法是生成一个静态函数,它返回一个被注释的类的列表,这样就不需要进行类扫描。
  • 一个非常好的资源是http://javadude.com/articles/annotations/index.html
票数 3
EN

Stack Overflow用户

发布于 2012-11-01 10:17:57

我想在运行时找到所有的子类。所以我一直在找android类扫描。这是我在网上收集到的最后一段代码。你会明白的。

代码语言:javascript
复制
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();
        }
    }
}
票数 4
EN

Stack Overflow用户

发布于 2012-07-10 20:18:14

编辑:

我在安卓问题追踪器中找到了本期ClassLoader.getResource(String)似乎“按预期工作”,因为它返回null。这是预期的,因为DalvikVM编译后不会保留资源。问题中列出了一些解决办法,但可能还有另一种方式来访问您想要的类。

使用PackageManager获取ApplicationInfo实例。ApplicationInfo有一个名为sourceDir的公共字段,它是指向该应用程序源目录位置的完整路径( String)。从这个File创建一个String,您应该能够导航到源目录中的包。一旦到了那里,您就可以使用我原来的答案中的方法来查找您要寻找的类。

代码语言:javascript
复制
String applicationSourceDir = 
    getPackageManager().getApplicationInfo(androidPackageName, 0).sourceDir;

/EDIT

您应该能够使用ClassLoader.getResource(String)获得特定包的URL (传入的String是您感兴趣的由路径分隔符而不是句点分隔的包名)。使用这个URL,您可以调用getFile(),从它可以为包文件夹创建一个File。从那里调用packageFile.listFiles(),您就有了类/子包。

使用子包进行递归,并使用类使用静态Class方法查找Class.forName(String)对象。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11421085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档