如何使用PathClassLoader替换已弃用的DexFile API?

时间:2018-05-01 16:36:10

标签: android jvm classloader dalvik dex

我有一个类,我在其中进行一些运行时注释扫描,但它使用deprecated DexFile APIs导致警告出现在LogCat中:

  • W/zygote64: Opening an oat file without a class loader. Are you using the deprecated DexFile APIs?

我想摆脱这条消息并使用正确的API。文档建议使用PathClassLoader,但我不知道它在功能上与DexFile的对应关系。我可以将PathClassLoaderDexFile实例结合使用,虽然它确实有效,但它会给我提供更多警告并需要更长时间才能扫描。为了清楚起见,我已经包含了我在下面写的注释扫描仪。如果有人可以建议如何摆脱这些警告信息以及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
    }
}

0 个答案:

没有答案