Jetpack Compose のアルファ版で作成したサンプルを1.0.0-beta06にマイグレーションした 

# はじめに
2020のアドベントカレンダーではJetpack ComposeのAlpha版を使ってQiitaビューアをサンプルアプリとして作ってみました。
現在はJetpack ComposeもBetaとしてバージョンを重ね、正式版のリリースも近づいて来ていると感じられます。

そこで、前回の記事のアルファ版からベータ版にマイグレーションをし、ここに至るまでAPIにどの様な変更が入り、開発者が注意すべき点がどの様なところにあるかをさらっと共有させていただきます。

# 主な対応内容
- Jetpack Compose を2021/4時点で最新である1.0.0-beta06に対応する。
    - APIコールなどをこのバージョンの仕様に合わせる
    - 通信やシリアライザを同一モジュール内に移す
- Android StudioについてArctic Fox Canary 15に対応する。
- その他諸々
- また、[このコメント](https://qiita.com/etctaro/items/a17681019c747f5e8b12#comment-2b9004a457801ca66ec4)の対応も入れています。

# 差分について
前回と今回の差分は以下から見ることができます。

- https://github.com/etctaro-tech/SampleComposeQiitaViewer/compare/v0.1-compose-alpha07...v0.2-compose-beta06

では、差分について細かく見ていきます。

# 関連ライブラリ類のアーティファクト変更、新規追加

`app/build.gradle`について、以下の通り変更を入れています。

```diff_groovy
dependencies {
      ...
-     implementation "androidx.ui:ui-tooling:$compose_version"
+     implementation "androidx.compose.ui:ui-tooling:$compose_version"

+     implementation 'androidx.activity:activity-compose:1.3.0-alpha07'

-     androidTestImplementation("androidx.ui:ui-test:$compose_version")
+     androidTestImplementation("androidx.compose.ui:ui-test-junit4:$compose_version")
}
```

(なぜか最後だけgroovy的じゃなくなっているのは内緒・・・) 

ポイントとしては、以下の通り。

- compose用のuiについては[androidx.compose.ui:ui-*](https://developer.android.com/jetpack/androidx/releases/compose-ui)というアーティファクトに移行した。
- ActivityとJetpack Composeを結び付けるためのAPIが[activity-composeという新しいアーティファクトに移行した](https://developer.android.com/jetpack/androidx/releases/activity#1.3.0-alpha01)。（setContentはここに含まれています。）

# setContentのパッケージ変更

`MainActivity.kt`

```diff_kotlin
+ import androidx.activity.compose.setContent
- import androidx.compose.ui.platform.setContent

...
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
...
```

なんと長らく使われてきた`setContent`が含まれるパッケージが変わってしまいました。
前述の通り、activity-composeに含まれているので、dependenciesの修正も必要です。

# ContextAmbientはLocalContextに。

`MainActiviyt.kt`

```diff_kotlin
- val context: Context = ContextAmbient.current
+ val context: Context = LocalContext.current
```

これもなかなか変更が激しいですが、Contextを取得する際に使っていたContextAmbientがAmbientContext→LocalContextという感じの歴史を辿ってクラス名が変わりました。
Ambientと名の付くAPIが全体的に変わっていました。

# パラメータ名の変更対応

`MainActivity.kt`

```diff_kotlin
- icon = { Icon(asset = Icons.Filled.Refresh) },
- modifier = Modifier.semantics { accessibilityLabel = "Refresh Button" }
+ icon = { Icon(imageVector = Icons.Filled.Refresh, contentDescription = null) },
+ modifier = Modifier.semantics { contentDescription = "Refresh Button" }
```

上記の様に、若干パラメータ名が変わっています。

また、IconはcontentDescriptionが必須のパラメータとなっています。(若干微妙。必要ないなら省略したい。)
アクセシビリティを考慮しなくて良い、装飾用のアイコンについてはnullにしてね、とのことです。

contentDescriptionについては、下記の通り、テスト用のAPIも合わせて変更が入っています。

```diff_kotlin
- composeTestRule.onNodeWithLabel("Refresh Button").performClick()
+ composeTestRule.onNodeWithContentDescription("Refresh Button").performClick()
```

# ScrollableColumnのRemove、LazyColumn推奨

`MainActivity.kt`

```diff_kotlin
-    ScrollableColumn(
-        modifier = Modifier.semantics { accessibilityLabel = "Item List" }) {
-        for (item in items) {
+    LazyColumn(
+        modifier = Modifier.semantics { contentDescription = "Item List" }) {
+        items(items) { item ->
            QiitaItem(title = item.title, url = item.url)
            Divider(color = Color.Black)
        }
```

楽にスクロール可能なリストが作れる！と短絡的に使っていたScrollableColumnですが、ガッツリ削除されました。
代わりにLazyColumnが推奨されていました。
確かに、リソースの効率を考慮するとそちらの方が良いですが、まさか消えるとは。

これに伴い、なんとなく書いたUIテストもどきのコード（と言っても、取得してリストに含まれる件数を取得するだけですが。）も変更を余儀なくされました。

LazyColumnはすでに記載した通り、必要になったら追加で要素を表示するというものになります。
例えば、リストの要素として、通信の結果20件が取得できるとします。この時に、画面には10件しか表示できない時、
LazyColumnが保持しているのは10件となります。(ScrollableColumnの場合は、見えなくても20件持っていることになっていました。)
画面をスクロールしてさらに後続の要素を表示しようとすると、残りの10件が表示される様になります。

このため、UIテストもどきのコードは、件数が一致しなくなるため失敗するようになります。

良い対処法がすぐには思いつかなかったのですが、
[beta06でリストの特定indexのところまでスクロールするAPIが追加された](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.0.0-beta06)ので、それを使ってみました。

```diff_kotlin
        composeTestRule.onNodeWithContentDescription("Item List").performScrollToIndex(19)
```

# kotinx.serializationがいい感じに修正された
[serializationをJetpack Composeを含んだモジュールに入れて利用すると、ビルドが終わらない](https://qiita.com/etctaro/items/a17681019c747f5e8b12#kotlinxserialization--jetpack-compose%E3%81%AE%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B%E3%82%92%E5%90%8C%E3%81%98%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E5%86%85%E3%81%A7%E5%AE%9F%E8%A3%85%E3%81%97%E3%81%9F%E5%A0%B4%E5%90%88%E3%83%93%E3%83%AB%E3%83%89%E3%81%8C%E7%B5%82%E3%82%8F%E3%82%89%E3%81%AA%E3%81%84)という問題が、Kotlin 1.4.21-2で修正されました。
ということで、1.4系最終（であると思われる）のKotlin 1.4.32にすることで、
kotlinx.serializationの問題も解決され、無事ビルドができる様になりました。

なお、Jetpack Composeのbeta01の時は、Kotlin 1.4.20でなければバージョンが合わずにビルドできなかったりしました。
こちらも1.0.0-beta06では無事解消されており、ビルドできるようになっています。

# その他
Arctic Foxのcanary 15に対応できるようにプラグインなどのバージョンを変えました。
また、Arctic FoxにEmbededされてるJDK(11系)を使うようにしました。

そして、もう一つ。JCenterからMavenCentralへの移行周りの対応をしました。
こちらは割とすんなりとうまく行けました。

# まとめ
そんなわけでJetpack ComposeをAlphaからBetaに上げたときの諸々を対応してみました。
まあ、新規にJetpack Composeを利用する時はもうBetaや、リリースされればRC、Stableから利用されると思いますので、
こんなマイグレーションをする人は少ないですかね。

# ソースコード
[GitHubのこちらのタグ](https://github.com/etctaro-tech/SampleComposeQiitaViewer/releases/tag/v0.2-compose-beta06)をご参照ください。