24

メソッドの 1 つで、リスト ビューで SmoothScrolling を使用します。このメソッドは API レベル 8 (FROYO) より前では使用できないため、TargetApi アノテーションを使用して、以前の SDK バージョンでメソッドが呼び出されないようにしました。

ご覧のとおり、クラス定義とクラスのオブジェクトを使用するステートメントの両方で TargetApi アノテーションを使用しますこれは必要以上です。

私たちの問題は、TargetApi アノテーションが考慮されておらず、バージョン ECLAIR (SDK 7) でエミュレーターがクラッシュすることです。トレースすると、バージョン 8 以降でのみ実行されるはずのコードがバージョン 7 でも実行されることがわかります。

何か不足していますか?

このコードはリスナーにあります:

@TargetApi(8)
private final class MyOnMenuExpandListener implements OnMenuExpandListener {
    @Override
    public void onMenuExpanded( int position ) {
        doScrollIfNeeded( position );
    }

    @Override
    public void onMenuCollapsed( int position ) {
        doScrollIfNeeded( position );
    }

    protected void doScrollIfNeeded( int position ) {
        if ( mListViewDocuments.getLastVisiblePosition() - 2 < position ) {
            mListViewDocuments.smoothScrollToPosition( position + 1 );
        }
    }
}

そして、リスナーは次のように登録されます:

@TargetApi(8)
private void allowSmothScrollIfSupported() {
    if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO ) {
        //This if should not be necessary with annotation but it is not taken into account by emulator
        Log.d( LOG_TAG, "Smooth scroll support installed." );
        folderContentAdapter.setOnMenuExpandListener( new MyOnMenuExpandListener() );
    }
}

ところで、デバッグ モードでコードを実行するため、問題は注釈の難読化とは関係ありません。

4

3 に答える 3

52

@TargetApiコードの実行を妨げるものではありません。単にコードに注釈を付けて、新しい API を条件付きで呼び出すだけであることがわかっている場合に、それらのコンパイラ エラーを防ぐためのものです。

次の行に沿って何かを追加する必要があります

if (Build.VERSION.SDK_INT > 7){
    //...
}
于 2012-08-31T08:25:35.550 に答える
5

これについてさらに1年近く考えて、@Guykunの答えに小さな補足を追加したいと思います:

@TargetApi は、開発者に「XXX android SDK の下でこのメソッドを使用しないでください」と言うツールによってのみ使用されます。通常は糸くず。

したがって、次のようなメソッドを設計する場合:

if (Build.VERSION.SDK_INT > 7){
    //...
}

次に @TargetApi( 7 ) をメソッドの署名に追加する必要があります。

ただし、else ステートメントを追加し、次のような Android のすべてのバージョンで機能する代替手段を提供する場合:

if (Build.VERSION.SDK_INT > 7){
    //...
} else {
    //...
}

@TargetApi( 7 ) をメソッドの署名に追加しないでください。そうしないと、他の開発者は API レベル 7 より前のメソッドを使用できないと考えるでしょうが、実際には、他の開発者にも同様に機能します。

そのため、このアノテーションは、メソッドがサポートする最小の API レベルを示すために、静的分析に使用する必要があります。のように:

@TargetApi( 7 )
public void foo() {
   if (Build.VERSION.SDK_INT > 7){
       //...
   else if (Build.VERSION.SDK_INT > 10){
       //...
   } 
}

さらに良いことに、で定義されている定数を使用しandroid.Build.VERSION_CODES.*ます。

ところで、これは、よりクリーンなコードを取得し、将来的にメソッドをパブリックに昇格させることを除いて、実際にはプライベート メソッドには役に立たないことに気付いたでしょう。

于 2013-08-26T17:48:50.017 に答える
1

より高い Api レベルを対象としたメソッドを使用するときに lint エラーを強制するには、RequiresApi代わりに使用TargetApiできます。バージョン コードを確認せずにメソッドを使用しようとすると、コンパイル エラーが発生します。

これは、ドキュメントがRequiresApiについて述べていることです

これは、古い @TargetApi アノテーションと目的が似ていますが、minSdkVersion を超えるメソッド内の警告を「抑制する」ために使用されるのではなく、これが呼び出し元の要件であることをより明確に表しています。

于 2016-10-11T18:41:22.340 に答える