我有一个类,我在其中进行一些运行时注释扫描,但它使用deprecated DexFile APIs导致警告出现在LogCat中:
W/zygote64: Opening an oat file without a class loader. Are you using the deprecated DexFile APIs?
。 我想摆脱这条消息并使用正确的API。文档建议使用PathClassLoader
,但我不知道它在功能上与DexFile
的对应关系。我可以将PathClassLoader
与DexFile
实例结合使用,虽然它确实有效,但它会给我提供更多警告并需要更长时间才能扫描。为了清楚起见,我已经包含了我在下面写的注释扫描仪。如果有人可以建议如何摆脱这些警告信息以及DexFile
的替代方案,那么在删除之后我就不会受到功能损坏的打击,我会非常感激。
class AnnotationScanner {
companion object {
fun classesWithAnnotation(
context: Context,
annotationClass: Class<out Annotation>,
packageName: String? = null
): Set<Class<*>> {
return Pair(context.packageCodePath, context.classLoader)
.letAllNotNull { packageCodePath, classLoader ->
Pair(DexFile(packageCodePath), classLoader)
}
?.letAllNotNull { dexFile, classLoader ->
dexFile
.entries()
?.toList()
?.filter { entry ->
filterByPackageName(packageName, entry)
}
?.map {
dexFile.loadClass(it, classLoader)
}
?.filter { aClass ->
filterByAnnotation(aClass, annotationClass)
}
?.toSet()
} ?: emptySet<Class<*>>().wlog { "No ${annotationClass.simpleName} annotated classes found" }
}
private fun filterByAnnotation(aClass: Class<*>?, annotationClass: Class<out Annotation>): Boolean {
return aClass
?.isAnnotationPresent(annotationClass)
?.also {
it.ifTrue {
Timber.w("Found ${annotationClass.simpleName} on $aClass")
}
}
?: false
}
private fun filterByPackageName(packageName: String?, entry: String) =
packageName?.let { entry.toLowerCase().startsWith(it.toLowerCase()) } ?: true
}
}