web-dev-qa-db-ja.com

AndroidAndroidライブラリのAPIレベルアノテーション

Androidライブラリを作成しています。 lbiraryのインターフェースの大部分は、AndroidAPIレベル10以上をサポートしています。ただし、一部の機能には、より高いAPIレベルが必要です。たとえば、ライブラリの一部にはBluetooth LowEnergy用のAPI18が必要です。

具体的には、ライブラリがClassAClassBClassCの3つのクラスを生成するとします。 ClassAはAPI10で利用可能な機能を使用し、ClassBはAPI14で利用可能な機能を使用し、ClassCはAPI18で利用可能な機能を使用します。

すでに構築されているのと同様に、誰かがプロジェクトに必要なAPIレベルを持たずに(適切なアノテーションで警告を抑制しない限り)ライブラリのクラスを使用するたびに、lintの問題(警告/エラー)をトリガーできるようにしたいです- lintが使用するNewApiの問題。

検索した後、私は次の可能な解決策を見つけました:

1)このソリューションはlintの方針に沿っていません:ライブラリを3つの.jarファイルに分割します。たとえば、API 10で利用可能な機能を使用するすべてのクラス(例ではClassA)を含むlib_10.jar、利用可能な機能を使用するすべてのクラスを含むlib_14.jar API 14(例ではClassB)およびAPI 18で使用可能な機能を使用するすべてのクラス(例ではClassC)を含むlib_18.jar。このソリューションは移植性を可能にしますが、コードベースのその後の保守性を複雑にし、コードの複製も必要になる可能性があります。

2)独自のアノテーションを作成し(たとえば、アノテーションが付けられたクラス/メソッドなどに必要な最小APIレベルを示す@RequireAndroidApi(API_LEVEL))、lint-api.jarhttp://tools.Android.com/tips/lint-custom-rules)を使用してカスタムlintルールを作成します。注釈付きのクラス/メソッドなどの使用...必要なAPIよりも低いAPI後で次のようになります。

@RequireAndroidApi(10)
Class ClassA {
}

@RequireAndroidApi(14)
Class ClassB {
}

@RequireAndroidApi(18)
Class ClassC {
}

問題は、lint APIの適切なドキュメントが見つからなかったことです。これにより、lintがすでにサポートしている機能の車輪が再発明されているようです(lintはすでに「NewApi」の問題をチェックしています)。

3)最後に、各クラスに必要なAPIレベルを次のように示すために、<SDK>/platform-tools/api/api-versions.xmlを編集することに成功しました。

<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>

これにより、lintはAndroidAPIの場合と同じ方法でNewApiの問題をトリガーしました。私はこのタイプのソリューションが好きです。なぜなら、それは車輪の再発明を行わず、さらにこの方法でスローされたエラーは、EclipseまたはAndroid St​​udioでプログラムされた推奨ソリューションを利用して問題に対処するからです(つまり、の「クイックフィックス」 Eclipse)。このソリューションの問題は、Android SDKに付属のapi-versions.xmlを編集する必要があることです。これにより、次のようないくつかの理由により、このソリューションはライブラリをリリースするための移植性が低くなります。a)api-versions.xmlファイルがローカルではないライブラリを使用しないプロジェクトを含む、すべてのAndroidプロジェクトのlintの動作をプロジェクトおよび変更します。 b)api-versions.xmlは、SDKがAndroid SDKマネージャーから更新されるたびに上書きされ、加えられた変更が上書きされます。

この「最小のAPIエラー/警告」を達成するためのより簡単な解決策があるのか​​、それともlintがあればいつでもlintが読み取ることができるプロジェクトディレクトリに配置できるapi-versions.xmlのような別のファイルを書く方法があるのだろうかと思っていました。問題のプロジェクトで実行されました(lint.xmlに似たもの)。

この問題の長い説明の間に私と一緒にいてくれてありがとう、そして私は前もってどんな助けにも感謝します。

14
madmare

独自のアノテーションを作成する必要はありません。Androidサポートライブラリの _@RequiresApi_ アノテーションが探しているものです。例:

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

このアノテーションは、APIレベルが低い可能性のあるコンテキストでsomeMethod()が使用された場合に警告するようにlintに指示します。

_@TargetApi_は異なることに注意してください。これは、注釈付きメソッドがターゲットAPIでのみ呼び出されることをリンターに保証するために使用されます。そうしないと、そのメソッドを使用しないように警告されます。したがって、_@TargetApi_を使用して、_@RequiresApi_によってトリガーされる糸くずの警告を消音することができます。

16
yuval