实现在Android的春天般的包扫描 [英] Implementing Spring-like package scanning in Android

查看:398
本文介绍了实现在Android的春天般的包扫描的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图实施一揽子扫描功能,类似于Spring的组件扫描,对于Android框架我开发。基本上,我希望能够指定一个基础包,如 com.foo.bar 和检索所有实例具有特定注释。我不希望有注册每个组件与我的框架,因为这会破坏自动扫描的目的。

根据我的研究,它似乎是不可能的Java获取给定的资源使用反射包名。不过,我简要地看着进入思考框架,如果​​我想知道有是一款Android兼容等同。如果没有,也许是一个稍微不太明显的方式来完成我想做的事情。

我朝春源了一下,看看他们是如何做到了这一点,但我不认为他们在做什么会在Dalvik运行时内工作。

更新

目前,以下code一直是最好的,我可以做些什么来检索包含特定注释的所有类,但坦率地说这是一个pretty的可怜的解决方案。这使得一些关于的ClassLoader 真的不安全的假设,再加上它会扫描(并加载)的所有应用程序类。

 公共设置<类<>> getClassesWithAnnotation(类和LT ;?延伸注释>注释){
    设置<类<>>类=新的HashSet<类<>>();
    现场dexField = PathClassLoader.class.getDeclaredField(mDexs);
    dexField.setAccessible(真正的);
    PathClassLoader类加载器=(PathClassLoader)Thread.currentThread()getContextClassLoader()。
    DexFile [] dexs =(DexFile [])dexField.get器(classloader);
    对于(DexFile DEX:dexs){
        枚举<字符串>条目= dex.entries();
        而(entries.hasMoreElements()){
            字符串项= entries.nextElement();
            类<> entryClass = dex.loadClass(入门,类加载器);
            如果(entryClass = NULL和放大器;!&安培; entryClass.isAnnotation present(注释)){
                classes.add(entryClass);
            }
        }
    }
    返回班;
}
 

解决方案

我分享乔普埃根的意见,并找到他的做法是好的。在Android中我尽量避免了通常的Web应用程序的特点,导致长期持久的应用程序启动。我不使用反射或包扫描。

但是,如果你想....如果我理解正确你想有一个注解的一类。而不是使用注解,你也可以使用标记接口(只是有更多的possibilites)。

1)看

2)AndroidAnnotations

我会preFER的方式 AndroidAnnotations 工作(也许是在AndroidAnnotations一体化是preferable方式):它会自动添加一个额外的编译步骤,生成源$ C ​​$ C,使用标准的Java注释处理工具。而不是运行时扫描所以您根据在编译时产生的注释执行code。

我觉得豆/ EBean注释可以为你工作(仅限于单个类)的 https://github.com/excilys/androidannotations/wiki/Enhance%20custom%20classes

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

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

I'm attempting to implement a package-scanning feature, similar to Spring's component-scan, for the Android framework I'm developing. Basically, I would like to be able to specify a base package, e.g. com.foo.bar and retrieve all Class instances that have a particular annotation. I don't want to have to register every component with my framework as that would defeat the purpose of the auto scanning.

Based on my research, it seems that it's not possible with Java to retrieve resources given a package name using reflection. However, I briefly looked into the Reflections framework, and I'm wondering if there is an Android-compatible equivalent. If not, perhaps there is a slightly less obvious way to accomplish what I want to do.

I looked into the Spring source a bit to see how they achieved this, but I don't think what they are doing would work within the Dalvik runtime.

Update

Currently, the below code has been the best I can do to retrieve all classes that contain a specific annotation, but frankly it's a pretty poor solution. It makes some really unsafe assumptions about the ClassLoader plus it scans (and loads) all application classes.

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;
}

解决方案

I share the opinion of Joop Eggen and find his approach a good one. In Android I try to avoid the usual web app features which lead to a long lasting application start. I do not use reflection or package scanning.

But if you want to .... if I understand it correctly you want to have an annotation for a class. Instead of using annotations you could also use marker interfaces (to just have more possibilites).

1) Look at

2) AndroidAnnotations

I would prefer the way AndroidAnnotations work (maybe an integration in AndroidAnnotations is the preferable way): It automatically adds an extra compilation step that generates source code, using the standard Java Annotation Processing Tool. So instead of runtime scanning you execute code based on the annotations generated during compile time.

I think the Bean/EBean annotation could work for you (only single class): https://github.com/excilys/androidannotations/wiki/Enhance%20custom%20classes

A scan-feature is not available, see this thread

3) Writing your own annotation processor

这篇关于实现在Android的春天般的包扫描的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆