Аннотации уровня API Android для Android-библиотек

Я пишу библиотеку Android. Подавляющее большинство интерфейсов в lbirary поддерживает Android API уровня 10 или выше. Однако для некоторых функций требуется более высокий уровень API. Например, часть библиотеки требует API 18 для Bluetooth Low Energy.

Ради конкретности предположим, что библиотека создает три класса ClassA , ClassB и ClassC . ClassA использует функциональные возможности, доступные в API 10, ClassB использует функциональные возможности, доступные в API 14, а ClassC использует функциональные возможности, доступные в API 18.

Я хочу, чтобы у вас была возможность вызвать проблему с ворсом (предупреждение / ошибка), когда кто-то использует класс из моей библиотеки, не имея требуемого уровня API в своем проекте (если только они не подавляют предупреждение с соответствующей аннотацией), аналогично уже встроенной, В проблеме NewApi, используемой lint.

После поиска я нашел следующие возможные решения:

1) Это решение не lib_10.jar : lib_10.jar библиотеку на три файла .jar, скажем, lib_10.jar который включает все классы, используя функциональные возможности, доступные в API 10 (ClassA в примере), lib_14.jar который включает в себя все Классы, использующие функциональные возможности, доступные в API 14 (ClassB в примере) и lib_18.jar который включает все классы, использующие функциональные возможности, доступные в API 18 (ClassC в примере). Это решение позволяет переносить, но усложняет более позднюю ремонтопригодность кодовой базы и потенциально может потребовать некоторого дублирования кода.

2) Создайте собственную аннотацию (скажем, @RequireAndroidApi(API_LEVEL) указывающую минимальный уровень API, требуемый аннотированным классом / методом / etc …) и используйте lint-api.jar ( http://tools.android.com/tips/lint-custom-rules ), чтобы создать пользовательские правила lint, которые проверяют использование любых аннотированных классов / методов / etc … с более низким API, чем требуется. Что-то, что позже будет выглядеть так:

 @RequireAndroidApi(10) Class ClassA { } @RequireAndroidApi(14) Class ClassB { } @RequireAndroidApi(18) Class ClassC { } 

Проблема в том, что я не мог найти хорошую документацию для API lint, и кажется, что это изобретает колесо для функциональности, которая уже поддерживается lint (lint уже проверяет проблему «NewApi»).

3) Наконец, мне удалось отредактировать <SDK>/platform-tools/api/api-versions.xml , чтобы указать уровень API, необходимый каждому классу, следующим образом:

 <api version="1"> ... <class name="package/path/ClassA" since="10"> <extends name="java/lang/Object" /> <method name="&lt;init>()V" /> </class> <class name="package/path/ClassB" since="14"> <extends name="java/lang/Object" /> <method name="&lt;init>()V" /> </class> <class name="package/path/ClassC" since="18"> <extends name="java/lang/Object" /> <method name="&lt;init>()V" /> </class> </api> 

Это вызвало необходимость запуска проблемы NewApi таким же образом, как и с API Android. Мне нравится этот тип решения, потому что он не изобретает колесо, и в дальнейшем любые ошибки, возникшие таким образом, будут использовать предлагаемые решения, запрограммированные в Eclipse или Android Studio, для решения этой проблемы (например, «быстрые исправления» в Eclipse). Проблема с этим решением заключается в том, что он требует редактирования api-versions.xml который поставляется с Android SDK, что делает это решение не очень удобным для выпуска библиотеки по нескольким причинам, включая: а) файл api-versions.xml не является локальным К проекту и изменяет поведение lint для всех проектов Android, включая те, которые не используют библиотеку; И b) api-versions.xml будет перезаписываться каждый раз, когда SDK обновляется из менеджера Android SDK, который перезаписывает сделанные изменения.

Мне было интересно, есть ли более простое решение для достижения этих «минимальных ошибок / предупреждений API» или если есть способ написать отдельный файл, похожий на api-versions.xml который можно поместить в каталог проекта, который может быть прочитан Lint, когда lint lint.xml в рассматриваемом проекте (что-то похожее на lint.xml ).

Спасибо за то, что вы были со мной в течение этого подробного описания проблемы, и я заранее ценю любую помощь.

Нет необходимости создавать собственную аннотацию, аннотация аннотированной поддержки @RequiresApi – это то, что вы ищете. Например:

 @RequiresApi(Build.VERSION_CODES.LOLLIPOP) public void someMethod() {} 

Эта аннотация сообщает lint, чтобы предупредить, используется ли someMethod() в контексте, который может иметь более низкий уровень API.

Обратите внимание, что @TargetApi отличается: он используется для обеспечения linter, который аннотированный метод будет вызываться только с помощью целевого API, в ситуации, когда он иначе предупреждал бы вас не использовать этот метод. Таким образом, @TargetApi можно использовать, чтобы отключить предупреждение о @RequiresApi вызванное @RequiresApi .

Я недавно сделал это в пользовательском классе вида, для которого необходим специальный конструктор для некоторых уровней api.

Я сделал это с аннотацией @TargetApi .

Если метод доступен только с уровня api 16:

 @TargetApi(16) public void someMethod () {} 

Это должно сделать трюк, включая ошибки ворса.