ターゲットSDKの警告対処のためにアノテーションが2つ用意されているので、違いをメモ
概要
TargetApi
は、SDKバージョンの警告を単純に無視するアノテーション
RequiresApi
は、SDKバージョンの責任を呼び出す側に転嫁させるアノテーション
具体的な挙動の違い
アノテーションを付与したメソッド内の挙動
Androidのアプリではしばしば、動作させる環境のSDKバージョンにより処理を分岐させる必要が生じる
例えば、minSdkVersion
が21(=Android L=5.0)かつtargetSdkVersion
が26(=Android O=8.0)のアプリに通知機能を搭載する場合、SDKバージョン26以上限定で「通知チャネル」を作成する必要がある
これを、以下のように実装する
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)
}
}
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でこのコードを入力すると、以下のように赤警告が出てしまう(エラーのように見えるが、ビルドは可能)
本ケースのように、構造上問題ないと保証できるが、表示されてしまっているSDKバージョンの警告は、TargetApi
またはRequiresApi
アノテーションを利用して消しておくのが良い
TargetApiを付与した場合
RequiresApiを付与した場合
アノテーションを付与したメソッドを呼び出す側の挙動
警告が出ていたメソッドにTargetApi
を利用した場合、そのメソッドの呼び出し側には特に変化はない
一方で、RequiresApi
を利用した場合は、呼び出し側がSDKバージョンの条件を満たすかどうか静的解析が波及する
TargetApiを付与した場合
RequiresApiを付与した場合
呼び出し元のメソッドについて静的解析が走り、先ほど付与したRequiresApi
の条件を満たすと判断できない場合、呼び出し元にも警告が出現する
この場合も同様に構造上問題ないと判断できるため、先ほどと同じアノテーションを付与して警告を消して良い
以上のように、RequiresApi
を利用する場合、プログラムの書き方によっては、連鎖的に複数のRequiresApi
を付与していく必要が出てくる可能性がある