15
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Androidのサポートライブラリに含まれるTargetApiとRequiresApiの違い

Posted at

ターゲットSDKの警告対処のためにアノテーションが2つ用意されているので、違いをメモ

概要

TargetApiは、SDKバージョンの警告を単純に無視するアノテーション
RequiresApiは、SDKバージョンの責任を呼び出す側に転嫁させるアノテーション

具体的な挙動の違い

アノテーションを付与したメソッド内の挙動

Androidのアプリではしばしば、動作させる環境のSDKバージョンにより処理を分岐させる必要が生じる

例えば、minSdkVersion21(=Android L=5.0)かつtargetSdkVersion26(=Android O=8.0)のアプリに通知機能を搭載する場合、SDKバージョン26以上限定で「通知チャネル」を作成する必要がある
これを、以下のように実装する

MainActivity.kt
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            createNotificationChannel()
        }
    }

    private fun createNotificationChannel() {
        NotificationUtil.createNotificationChannel(this)
    }
}
NotificationUtil.kt
object NotificationUtil {

    fun createNotificationChannel(context: Context) {
        context.applicationContext.apply {
            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            val channel = NotificationChannel(
                    "channel_news",
                    getString(R.string.notification_channel_news_label),
                    NotificationManager.IMPORTANCE_DEFAULT
            )
            notificationManager.createNotificationChannel(channel)
        }
    }
}

NotificationUtilオブジェクトのcreateNotificationChannelメソッド内に存在するNotificationChannelのインスタンス化は、SDKバージョン26以上を必要とするAndroidのAPIであるため注意する必要があるが、呼び出し元であるMainActivityのonCreateメソッド内で「SDKバージョン26(=O)以上」と分岐しているため、構造上問題ない
しかし、Android Studioでこのコードを入力すると、以下のように赤警告が出てしまう(エラーのように見えるが、ビルドは可能)
target_sdk_alert.png

本ケースのように、構造上問題ないと保証できるが、表示されてしまっているSDKバージョンの警告は、TargetApiまたはRequiresApiアノテーションを利用して消しておくのが良い

TargetApiを付与した場合

警告が消える
surpass_with_target_api.png

RequiresApiを付与した場合

こちらも同様に警告が消え、TargetApiとの違いはない
surpass_with_requires_api.png

アノテーションを付与したメソッドを呼び出す側の挙動

警告が出ていたメソッドにTargetApiを利用した場合、そのメソッドの呼び出し側には特に変化はない
一方で、RequiresApiを利用した場合は、呼び出し側がSDKバージョンの条件を満たすかどうか静的解析が波及する

TargetApiを付与した場合

もともと警告は出ておらず、変化なし
caller_when_target_api.png

RequiresApiを付与した場合

呼び出し元のメソッドについて静的解析が走り、先ほど付与したRequiresApiの条件を満たすと判断できない場合、呼び出し元にも警告が出現する
caller_when_requires_api.png

この場合も同様に構造上問題ないと判断できるため、先ほどと同じアノテーションを付与して警告を消して良い
surpass_with_requires_api_in_caller.png

以上のように、RequiresApiを利用する場合、プログラムの書き方によっては、連鎖的に複数のRequiresApiを付与していく必要が出てくる可能性がある

参考

15
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?