Зачем использовать отражение для HttpResponseCache?
В документации HttpResponseCache
есть раздел:
Работа с более ранними выпусками
Этот класс был добавлен в Android 4.0 (Ice Cream Sandwich). Используйте отражение, чтобы включить кэш ответов, не влияя на более ранние выпуски:
try { File httpCacheDir = new File(context.getCacheDir(), "http"); long httpCacheSize = 10 * 1024 * 1024; // 10 MiB Class.forName("android.net.http.HttpResponseCache") .getMethod("install", File.class, long.class) .invoke(null, httpCacheDir, httpCacheSize); } catch (Exception httpResponseCacheNotAvailable) { }
Вы можете увидеть этот призыв с помощью размышлений в вопросах здесь о SO (например, здесь) и примерах в Интернете. Я также взял код, который содержит этот точный фрагмент для настройки кэша (включая комментарий, так что, вероятно, это просто copypasta). Тем не менее, я не совсем понимаю, почему вы должны использовать отражение здесь.
Обычно, когда я хочу использовать метод, добавленный на определенном уровне API выше моего определенного minSdkVersion
Я бы использовал следующий шаблон:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// do something here
}
так почему же это не шаблон по умолчанию для HttpResponseCache
, В чем преимущество использования отражения? Это, конечно, не улучшает читаемость моего кода. Есть ли HttpResponseCache
на самом деле работать ниже ICS при использовании отражения таким образом?
РЕДАКТИРОВАТЬ: у меня нет старого устройства Android здесь, и мой эмулятор вообще не запускается, поэтому я не могу просто проверить его в данный момент. Может быть, это просто ужасно падает без отражения.
2 ответа
В чем преимущество использования отражения?
Сначала цитируем документацию:
Этот класс был добавлен в Android 4.0 (Ice Cream Sandwich).
Под "был добавлен" они подразумевают "был добавлен в Android SDK", а под "Мороженым сэндвичем" они на самом деле подразумевают Android 3.2 (уровень API 13), основанный на остальных JavaDocs.
Тем не менее HttpResponseCache
Сам класс существует в рамках дольше, надеюсь, начиная с Android 1.0, учитывая их рекомендации. Тем не менее, этот класс был отмечен @hide
аннотации, поэтому он не может использоваться приложениями непосредственно до уровня API 13.
Ваш блок защиты версии Java с помощью Build
избегать ссылки на этот класс непосредственно на старых устройствах. Однако на самом деле он также не настраивает кеш на старых устройствах. Их подход будет работать на всех версиях Android и позволит вам настроить кеш, так как класс существует с самого начала.
Довольно редко Google явно разрешает использование рефлексии для поиска скрытых классов или методов таким образом, поэтому вы не часто видите это в официальной документации.
К сожалению, ваше предложение не будет работать для более старых версий. Подумайте о следующем. Они добавили метод install(File, long)
на новую версию. Но код, который вызывает этот метод, упакован в другой jar.
Теперь у вас есть старая версия jar, которая содержит HttpResponseCache
и новая версия фляги, которая называет это. Если ты пишешь там
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
cache.install(file, number);
}
NoSuchMethodError
будет брошено, даже если выражение if ложно. Использование отражения - уродливый, но полезный метод для предотвращения этого.