Как я могу использовать PathClassLoader для замены устаревших API DexFile?

У меня есть класс, в котором я выполняю сканирование аннотаций во время выполнения, но он использует устаревшие API DexFile, который вызывает предупреждение в 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
    }
}

Вы нашли способ обойти это?

strangetimes 16.09.2018 14:30

Нет, у меня никогда не было времени погрузиться в поиски лучшего решения. Я полагаю, что лучшим решением было бы избежать обработки аннотаций во время выполнения.

Carter Hudson 21.09.2018 20:50

Спасибо, я тоже этим занимаюсь

strangetimes 21.09.2018 21:18
5
3
2 010
0

Другие вопросы по теме