Android扫描注解

最近专注在开源项目AndroidJSSDKCore上,目前采取简单粗暴的方案,在android的apk包中扫描指定注解。可参见具体使用方式;

直接上代码喽~~~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/**
* 扫描获得所有标注注解clazz的java Class
*
* @param context context
* @param annotationClass 注解class
* @param applicationId applicationId
* @param packageNameList 需要扫描的package
* @return
*/

private List<Class> scanAllClass(Context context, Class annotationClass, String applicationId, String... packageNameList) {
try {
ApplicationInfo applicationInfo = context.getPackageManager().getApplicationInfo(applicationId, 0);
String apkName = applicationInfo.sourceDir;
DexFile dexFile = new DexFile(apkName);
PathClassLoader classLoader = new PathClassLoader(apkName, Thread.currentThread().getContextClassLoader());
List<Class> classList = new ArrayList<>();
Enumeration<String> entries = dexFile.entries();
while (entries.hasMoreElements()) {
String entry = entries.nextElement();
if (isNeedClass(entry, packageNameList)) {
Class<?> entryClass = classLoader.loadClass(entry);
if (entryClass != null) {
Annotation[] annotations = entryClass.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation.annotationType().equals(annotationClass)) {
classList.add(entryClass);
}
}
}
}
}
return classList;
} catch (PackageManager.NameNotFoundException e) {
LogTool.error(e.getMessage());
} catch (IOException e) {
LogTool.error(e.getMessage());
} catch (ClassNotFoundException e) {
LogTool.error(e.getMessage());
}
return null;
}

private boolean isNeedClass(String entry, String... packageNameList) {

for (String packageName : packageNameList) {
if (entry.startsWith(packageName)) {
return true;
}
}
return false;
}