サンプルアプリを作成して、描画処理(再Compose)の周期を観測してみました。
その結果を紹介します。
※環境:Android Studio Giraffe | 2022.3.1 Patch 1
Kotlin 1.8.10
Compose Compiler 1.4.3
スポンサーリンク
描画処理の周期
描画処理は周期的(1/60秒)に起動されています。
これにより、画面の更新やシームレスなアニメーションを表現しています。
※詳細は「Composeによるアプリ画面の描画」を参照
スポンサーリンク
周期の観測
描画処理の周期的な起動を観測するために、サンプルアプリを作成してみました。
// 参考: 1/60[s] ≒ 16.67[ms] private const val S_PERIOD = 5L // 5[ms] //private const val S_PERIOD = 20L // 20[ms] class MainActivity : ComponentActivity() { @SuppressLint("CoroutineCreationDuringComposition") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MyApplicationTheme { // countの変更を追跡 var _count = remember { mutableStateOf(0) } Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { FramerateCheck(count = _count.value) } // 別スレッドでcountを更新 val _coroutineScope = rememberCoroutineScope() _coroutineScope.launch(Dispatchers.Default) { delay(5000) repeat(100) { _count.value++ delay(S_PERIOD) } } } } } } private var prev_tim: Long = 0L @Composable fun FramerateCheck(count: Int) { // 周期の計測 val _crrt_tim = System.currentTimeMillis() Log.i(TAG, "Period = ${_crrt_tim - prev_tim}[ms] (Count = ${count})") prev_tim = _crrt_tim // コンテンツの実態 Text(text = "Count = ${count}") }
観測の方法は単純です。「描画処理の周期 > S_RERIOD(状態の更新間隔)」であれば、「再Composeの実行間隔 == 描画処理の周期」になります。
スポンサーリンク
周期の考察
観測の結果、「描画処理の周期は1/60秒である」ことが理解できます。
従って、Composable関数は「1/60秒間隔」の実行になるので、リアルタイム性のある処理を期待しても、正しく動きません。
アプリ開発者は、その点を認識しておく必要があると思います。
※参考:1/60(秒)=16.67(ms)、1/60×2(秒)=16.67×2=33.33(ms)
【 S_PERIOD = 5(ms) 】Period = 17[ms] (Count = 79) ... 1 Period = 16[ms] (Count = 81) ... 2 Period = 18[ms] (Count = 84) ... 3 Period = 16[ms] (Count = 86) ... 4 Period = 17[ms] (Count = 89) ... 5 Period = 16[ms] (Count = 92) ... 6 Period = 17[ms] (Count = 94) ... 7 Period = 17[ms] (Count = 97) ... 8 Period = 16[ms] (Count = 99) ... 9 Period = 18[ms] (Count = 100) ... 10 ※1~10の平均:16.6(ms)【 S_PERIOD = 20(ms) 】
Period = 16[ms] (Count = 91) ... 1 Period = 34[ms] (Count = 92) ... 2 Period = 16[ms] (Count = 93) ... 3 Period = 17[ms] (Count = 94) ... 4 Period = 33[ms] (Count = 95) ... 5 Period = 17[ms] (Count = 96) ... 6 Period = 17[ms] (Count = 97) ... 7 Period = 16[ms] (Count = 98) ... 8 Period = 34[ms] (Count = 99) ... 9 Period = 16[ms] (Count = 100) ... 10 ※1,3,4,6,7,8,10の平均:16.4(ms) 2,5,9の平均:33.7{ms)
スポンサーリンク
関連記事:
プロジェクトのビルドで「Something went wrong while checking for version compatibility between the Compose Compiler and the Kotlin Compiler.」とメッセージを吐き、エラーになる場合があります。 既存のプロジェクトを新しくリリースされたAndroid Studioでビルドした場合に頻発します。 先日、「Giraffe|2022.3.1」がリリース(2023.07)されて、早速、ビルドをしたら発生しました。 その対処方法を説明します。 ※環境:Android Studio Giraffe | 2022.3.1 ...
表示の変わらないUI要素(Composable関数)に対して行われる再Composeは無駄な処理です。 ですので、極力排除したいところですが、表示が変わらないため、画面上からの判断が難しくなっています。 このようなとき、Layout Inspectorを利用すると、無駄な再Composeを見つけ出すことが出来ます。 ※環境:Android Studio Giraffe | 2022.3.1 Patch 1 ...
Jetpack ComposeはAndroidシステムの新たなUIフレームワークです。従来のViewシステムと、アプリ画面の描画の仕組みが異なります。 このJetpack Composeによるアプリ画面の描画について、仕組みの大枠をまとめます。 ※環境:Android Studio Giraffe | 2022.3.1 Patch 1 Kotlin 1.8.10 Compose Compiler 1.4.3 ...
Jetpack Composeは描画処理の軽量化(消費リソース量の削減)をするために、表示の変更されたUI要素のみを再Composeし、表示の変わらないUI要素をスキップします。これにより、高い表示パフォーマンスを維持しています。 しかし、スキップが正常に行われないとしても、アプリの画面に現れて来ません。なぜなら、同じ表示を無駄に繰り返すことになるからです。 アプリは動くけれど動作が鈍いならば、真っ先に疑うポイントです。不要な再Composeが行われている可能性が考えられます。 これは気付かないうちに蓄積し易い不具合です。ですので、再Composeとスキップについて理解し、予防に努めることをお勧めします。 今回は「再Composeとスキップ」について、まとめます。 ※環境:Android Studio Giraffe | 2022.3.1 Patch 1 Kotlin 1.8.10 Compose Compiler 1.4.3 ...
mutableStateOfはComposable関数ではありません。 ですので、Composable関数内にある必要はなく、どこでも記述できます。 Activityから表示の更新を発行する方法として使えそうです。 ※環境:Android Studio Giraffe | 2022.3.1 Patch 1 Kotlin 1.8.10 Compose Compiler 1.4.3 ...
状態の保持(remenber)はアプリの画面(UI)を制御・管理するために必要な動作です。 再Composeのスケジューリング(mutableStateOf)に並び、Jetpack Composeの重要な技術の一つです。 今回は「再Composeを超えて状態の保持」について、まとめます。 ※環境:Android Studio Giraffe | 2022.3.1 Patch 1 Kotlin 1.8.10 Compose Compiler 1.4.3 ...
再Composeのスケジューリング(mutableStateOf)はアプリのパフォーマンスに直結する動作です。 状態の保持(remember)に並び、Jetpack Composeの重要な技術の一つです。 今回は「再Composeのスケジューリング」について、まとめます。 ※環境:Android Studio Giraffe | 2022.3.1 Patch 1 Kotlin 1.8.10 Compose Compiler 1.4.3 ...
CompositionLocalはUIツリーで発生する状態のバケツリレーを解決してくれます。 また、広く共有したい状態の定義にも適しています。例えば、「ツリーのある階層以下に対して」などと言った場合です。 CompositionLocalについて、まとめます。 ※環境:Android Studio Giraffe | 2022.3.1 Patch 1 Kotlin 1.8.10 Compose Compiler 1.4.3 ...
CompositionLocalはUIツリーにローカルな変数を確保します。 その変数の参照キーはcompositionLocalOf関数(以降、Dynamic側と呼ぶ)によって返されるCompositionLocalインスタンスです。 このインスタンスを返す方法に、もう一つ、staticCompositionLocalOf関数(以降、Static側と呼ぶ)があります。 この両者の違いをまとめます。 ※環境:Android Studio Giraffe | 2022.3.1 Patch 1 Kotlin 1.8.10 Compose Compiler 1.4.3 ...
CompositionLocalはシステムにより提供されているものがあります。 プログラミングに有益で利用頻度の高いものが用意されています。例えば、LocalContextやLocalConfigurationなどです。 ※環境:Android Studio Giraffe | 2022.3.1 Patch 1 Kotlin 1.8.10 Compose Compiler 1.4.3 ...
「Android Studio Giraffe」の作成するプロジェクトは、Jetpack Composeの利用が推奨されます。 今後、Viewシステムに代わり、Jetpack Composeが主流になるようです。 ※環境:Android Studio Giraffe | 2022.3.1 Patch 1 Kotlin 1.8.10 Compose Compiler 1.4.3 ...
「Android Studio Giraffe」の作成するプロジェクトは、Jetpack Composeの利用が推奨されます。 そして、作成されたプロジェクトは、Material Designeに準拠したテーマが指定されます。 ※環境:Android Studio Giraffe | 2022.3.1 Patch 1 Kotlin 1.8.10 Compose Compiler 1.4.3 ...
Android StudioにおけるJetpack Composeプロジェクトは、エディタ上でUIのプレビューが行えます。 Kotlinで記述した画面構成(UIツリー)が視覚的に確認できるので、とても便利です。 さらに、色々な表示条件の設定が行えるので、使いこなせば更に利便性が向上します。 ※この記事の執筆中にドキュメント「コンポーザブルのプレビューで UI をプレビューする」を見つけました。記事はこのドキュメントと重複する部分が多いです。ドキュメントも参考にして下さい。 ※環境:Android Studio Giraffe | 2022.3.1 Patch 3 Kotlin 1.8.10 Compose Compiler 1.4.3 ...
Jetpack Composeが提供する既存のUI要素(Compose UI)は、必ずModifierを引数に持ちます。 このModifierの役割はUI要素へ装飾や機能拡張を追加することですが、裏でアプリ画面の描画処理と密接に関連しており、UI要素よりもシステム側に近い存在です。 理解せずに誤った使い方をすれば、装飾や機能拡張の域を脱してUI要素が表示されないこともあり、思ったようなアプリ画面は望めません。 Modifierについて、まとめます。 ※環境:Android Studio Hedgehog | 2023.1.1 Kotlin 1.8.10 Compose Compiler 1.4.3 ...
スポンサーリンク