最近专注在开源项目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; }
|