Android 16 プラットフォームには、アプリに影響する可能性がある動作変更が含まれています。下記の動作変更は、targetSdkVersion
に関係なく、Android 16 上で稼働するすべてのアプリに適用されます。該当する場合は、アプリをテストし、必要に応じて修正して、これらの変更に対応する必要があります。
Android 16 をターゲットとするアプリにのみ影響する動作変更のリストも必ずご確認ください。
コア機能
Android 16 には、Android システムのさまざまなコア機能を変更または拡張する次の変更が含まれています。
JobScheduler の割り当ての最適化
Android 16 以降、Google は次の要素に基づいて、通常のジョブ実行とエクスプレス ジョブ実行のランタイム割り当てを調整しています。
- アプリがどのアプリ スタンバイ バケットに属しているか: Android 16 では、アクティブなスタンバイ バケットに、十分なランタイム割り当てが適用されるようになります。
- アプリがトップ状態のときにジョブの実行が開始された場合: Android 16 では、アプリがユーザーに表示されている間に開始され、アプリが非表示になった後に続行されるジョブは、ジョブのランタイム割り当てに準拠します。
- フォアグラウンド サービスを実行中にジョブが実行されている場合: Android 16 では、フォアグラウンド サービスと同時に実行されているジョブは、ジョブのランタイム割り当てに準拠します。ユーザーが開始するデータ転送にジョブを使用している場合は、代わりにユーザーが開始するデータ転送ジョブの使用を検討してください。
この変更は、WorkManager、JobScheduler、DownloadManager を使用してスケジュール設定されたタスクに影響します。ジョブが停止した理由をデバッグするには、WorkInfo.getStopReason()
を呼び出してジョブが停止した理由をロギングすることをおすすめします(JobScheduler ジョブの場合は JobParameters.getStopReason()
を呼び出します)。
バッテリー最適化のベスト プラクティスについて詳しくは、タスク スケジューリング API のバッテリー使用量を最適化するに関するガイダンスをご覧ください。
また、Android 16 で導入された新しい JobScheduler#getPendingJobReasonsHistory
API を利用して、ジョブが実行されなかった理由を把握することをおすすめします。
テスト
アプリの動作をテストするには、アプリが Android 16 デバイスで実行されている限り、特定のジョブ割り当て最適化のオーバーライドを有効にできます。
「トップ状態はジョブのランタイム割り当てに準拠する」の適用を無効にするには、次の adb
コマンドを実行します。
adb shell am compat enable OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS APP_PACKAGE_NAME
「フォアグラウンド サービスと同時に実行されているジョブはジョブのランタイム割り当てに準拠する」の適用を無効にするには、次の adb
コマンドを実行します。
adb shell am compat enable OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS APP_PACKAGE_NAME
特定のアプリ スタンバイ バケットの動作をテストするには、次の adb
コマンドを使用してアプリのアプリ スタンバイ バケットを設定します。
adb shell am set-standby-bucket APP_PACKAGE_NAME active|working_set|frequent|rare|restricted
アプリが属するアプリ スタンバイ バケットを確認するには、次の adb
コマンドを使用してアプリのアプリ スタンバイ バケットを取得します。
adb shell am get-standby-bucket APP_PACKAGE_NAME
放棄された空のジョブの停止理由
放棄されたジョブは、ジョブに関連付けられた JobParameters
オブジェクトがガベージ コレクションされたものの、JobService#jobFinished(JobParameters,
boolean)
が呼び出されず、ジョブの完了が通知されていない場合に発生します。これは、アプリが認識せずにジョブが実行され、スケジュールが変更されている可能性があることを示します。
JobScheduler に依存するアプリは、JobParameters
オブジェクトへの強参照を維持しないため、タイムアウトには STOP_REASON_TIMEOUT
ではなく、新しいジョブ停止理由 STOP_REASON_TIMEOUT_ABANDONED
が付与されます。
新しい放棄された停止理由が頻繁に発生する場合、システムは緩和策を講じてジョブの頻度を減らします。
アプリは、新しい停止理由を使用して、放棄されたジョブを検出して削減する必要があります。
WorkManager、AsyncTask、DownloadManager を使用している場合、これらの API はアプリに代わってジョブのライフサイクルを管理するため、影響を受けません。
JobInfo#setImportantWhileForeground のサポートを完全に終了
JobInfo.Builder#setImportantWhileForeground(boolean)
メソッドは、スケジュール設定アプリがフォアグラウンドにある間、またはバックグラウンドの制限を一時的に免除されている間のジョブの重要度を示します。
このメソッドは、Android 12(API レベル 31)で非推奨になりました。Android 16 以降では、このメソッドは効果的に機能しなくなり、このメソッドの呼び出しは無視されます。
この機能の削除は JobInfo#isImportantWhileForeground()
にも適用されます。Android 16 以降では、メソッドが呼び出されると、メソッドは false
を返します。
順序付きブロードキャストの優先度スコープがグローバルではなくなった
Android 应用可以为广播接收器定义优先级,以控制接收器接收和处理广播的顺序。对于清单声明的接收器,应用可以使用 android:priority
属性来定义优先级;对于上下文注册的接收器,应用可以使用 IntentFilter#setPriority()
API 来定义优先级。发送广播时,系统会按接收器的优先级(从高到低)将其传送给接收器。
在 Android 16 中,无法保证使用 android:priority
属性或 IntentFilter#setPriority()
在不同进程中传送广播的顺序。广播优先级仅在同一应用进程内有效,而不会跨所有进程有效。
此外,广播优先级将自动限制在 (SYSTEM_LOW_PRIORITY
+ 1, SYSTEM_HIGH_PRIORITY
- 1) 的范围内。只有系统组件才能将 SYSTEM_LOW_PRIORITY
、SYSTEM_HIGH_PRIORITY
设置为广播优先级。
如果您的应用执行以下任一操作,可能会受到影响:
- 您的应用声明了具有相同广播 intent 的多个进程,并且希望根据优先级以特定顺序接收这些 intent。
- 您的应用进程与其他进程交互,并期望以特定顺序接收广播 intent。
如果进程需要相互协调,则应使用其他协调渠道进行通信。
ART 内部の変更
Android 16 包含 Android 运行时 (ART) 的最新更新,这些更新可提升 Android 运行时 (ART) 的性能,并支持更多 Java 功能。通过 Google Play 系统更新,搭载 Android 12(API 级别 31)及更高版本的 10 亿多部设备也将受益于这些改进。
发布这些变更后,依赖于 ART 内部结构的库和应用代码在搭载 Android 16 的设备以及通过 Google Play 系统更新来更新 ART 模块的较低 Android 版本上可能无法正常运行。
依赖于内部结构(例如非 SDK 接口)始终会导致兼容性问题,但避免依赖于利用内部 ART 结构的代码(或包含代码的库)尤为重要,因为 ART 更改与设备所运行的平台版本无关,并且会通过 Google Play 系统更新推送到超过 10 亿部设备。
所有开发者都应在 Android 16 上对其应用进行全面测试,以检查其应用是否受到影响。此外,请查看已知问题,了解您的应用是否依赖于我们发现的任何依赖于内部 ART 结构的库。如果您的应用代码或库依赖项受到影响,请尽可能寻找公共 API 替代方案,并在问题跟踪器中创建功能请求,为新用例请求公共 API。
16 KB ページサイズの互換モード
Android 15 introduced support for 16 KB memory pages to optimize performance of the platform. Android 16 adds a compatibility mode, allowing some apps built for 4 KB memory pages to run on a device configured for 16 KB memory pages.
If Android detects that your app has 4 KB aligned memory pages, it
automatically uses compatibility mode and display a notification dialog to the
user. Setting the android:pageSizeCompat
property in the AndroidManifest.xml
to enable the backwards compatibility mode will prevent the display of the
dialog when your app launches. For best performance, reliability, and stability,
your app should still be 16 KB aligned. Check out
our recent blog post
on updating your apps to support 16 KB memory pages for more details.
![](https://developer.android.google.cn/static/about/versions/16/images/16-kb-compat-mode-dialog.png?authuser=5&hl=ja)
ユーザー エクスペリエンスとシステム UI
Android 16 には、より一貫性があり直感的なユーザー エクスペリエンスを実現するための以下の変更が含まれています。
ユーザー補助の妨げになる通知の非推奨
Android 16 では、announceForAccessibility
の使用や TYPE_ANNOUNCEMENT
ユーザー補助イベントのディスパッチを特徴とするユーザー補助通知が非推奨になりました。これにより、TalkBack と Android のスクリーン リーダーのユーザーに対して一貫性のないユーザー エクスペリエンスが生じる可能性があります。代替手段を使用すると、さまざまな Android 支援技術で幅広いユーザーのニーズに対応できます。
代替手段の例:
- ウィンドウの変更など、UI の大幅な変更の場合は、
Activity.setTitle(CharSequence)
とsetAccessibilityPaneTitle(java.lang.CharSequence)
を使用します。Compose でModifier.semantics { paneTitle = "paneTitle" }
を使用する - 重要な UI の変更をユーザーに通知するには、
setAccessibilityLiveRegion(int)
を使用します。Compose では、Modifier.semantics { liveRegion = LiveRegionMode.[Polite|Assertive]}
を使用します。ビューが更新されるたびにお知らせが生成される可能性があるため、これらの関数は慎重に使用する必要があります。 - エラーをユーザーに通知するには、タイプ
AccessibilityEvent#CONTENT_CHANGE_TYPE_ERROR
のAccessibilityEvent
を送信し、AccessibilityNodeInfo#setError(CharSequence)
を設定するか、TextView#setError(CharSequence)
を使用します。
非推奨の announceForAccessibility
API のリファレンス ドキュメントには、推奨される代替方法の詳細が記載されています。
3 ボタン ナビゲーションのサポート
Android 16 では、予測型「戻る」に適切に移行したアプリの 3 ボタン ナビゲーションに、予測型「戻る」のサポートが追加されています。戻るボタンを長押しすると、予測型「戻る」アニメーションが開始され、戻るスワイプで移動する先のプレビューが表示されます。
この動作は、システム アニメーション(ホームに戻る、タスク間、アクティビティ間)など、予測型「戻る」アニメーションをサポートするシステムのすべての領域に適用されます。
セキュリティ
Android 16 では、システムのセキュリティを強化し、悪意のあるアプリからアプリとユーザーを保護するための変更が加えられています。
インテント リダイレクト攻撃に対するセキュリティを強化
Android 16 では、一般的な Intent
リダイレクト攻撃に対するデフォルトのセキュリティが提供され、互換性とデベロッパーの変更が最小限に抑えられます。
Intent
リダイレクト エクスプロイトに対して、デフォルトでセキュリティ強化ソリューションを導入します。通常、インテントを使用しているアプリでは互換性の問題は発生しません。Google は開発プロセス全体で指標を収集し、どのアプリで不具合が発生する可能性があるかをモニタリングしています。
Android のインテント リダイレクトは、攻撃者が脆弱なアプリのコンテキストで新しいコンポーネントの起動に使用されるインテントの内容を部分的または完全に制御できる一方で、被害を受けるアプリが(「トップレベル」の)インテントの Extras フィールドで信頼できないサブレベル インテントを起動する場合に発生します。これにより、攻撃者のアプリが被害者のアプリのコンテキストで非公開コンポーネントを起動したり、特権アクションをトリガーしたり、機密データへの URI アクセスを取得したりする可能性があります。これにより、データの盗難や任意のコードの実行につながる可能性があります。
インテントのリダイレクト処理をオプトアウトする
Android 16 では、アプリが起動時のセキュリティ保護をオプトアウトできる新しい API が導入されています。これは、デフォルトのセキュリティ動作が正当なアプリのユースケースを妨げている特定のケースで必要になる場合があります。
Android 16 以降をターゲットとするアプリの場合
Intent オブジェクトで removeLaunchSecurityProtection()
メソッドを直接使用できます。
val i = intent
val iSublevel: Intent? = i.getParcelableExtra("sub_intent")
iSublevel?.removeLaunchSecurityProtection() // Opt out from hardening
iSublevel?.let { startActivity(it) }
Android 15(API レベル 35)以前をターゲットとするアプリの場合
推奨されていませんが、リフレクションを使用して removeLaunchSecurityProtection()
メソッドにアクセスできます。
val i = intent
val iSublevel: Intent? = i.getParcelableExtra("sub_intent", Intent::class.java)
try {
val removeLaunchSecurityProtection = Intent::class.java.getDeclaredMethod("removeLaunchSecurityProtection")
removeLaunchSecurityProtection.invoke(iSublevel)
} catch (e: Exception) {
// Handle the exception, e.g., log it
} // Opt-out from the security hardening using reflection
iSublevel?.let { startActivity(it) }