🖼️

Coilを3系に上げたときのメモ

2025/01/07に公開

はじめに

クラシルリワードのAndroid開発では、ImageLoaderとしてCoilを採用しています。
先日Coilのメジャーアップデート(2 -> 3)[1]がありました。
更新にあたり、思ったより対応が必要な部分が多くあったため、対応した内容を記録として残しておきたいと思います📝

何が変わるのか

3系になったことで大きく変わる点は主に以下の2つです。

  1. package nameがcoilからcoil3になる
  2. デフォルトでネットワークからの画像の読み込みをサポートしなくなる

それぞれについて詳しく見ていきます。

package nameの変更に対応する

package nameが変わったことで、Coilのimportを全て修正する必要があります。
以下はよく使うAsyncImageの例ですが、これ以外のimportもすべて手直ししないといけません😓

+    import coil.compose.AsyncImage
-    import coil3.compose.AsyncImage

幸いクラシルリワードではAsyncImageを以下のようにラップして使ってたので、UI componentのあちこちでエラーが起きることはなかったです。

@Composable
fun AsyncImage(
    modifier: Modifier = Modifier,
    imageUrl: String,
    contentDescription: String? = null,
    alignment: Alignment = Alignment.Center,
    contentScale: ContentScale = ContentScale.Fit,
    placeHolder: Painter? = painterResource(R.drawable.background_image_placeholder),
    error: Painter? = painterResource(R.drawable.background_image_placeholder)
) {
    // CoilのAsyncImage
    AsyncImage(
        modifier = modifier,
        model = imageUrl,
        contentDescription = contentDescription,
        alignment = alignment,
        contentScale = contentScale,
        placeholder = placeHolder,
        error = error
    )
}

ネットワーク画像が読み込めるようにする

上記の通り、Coil3ではデフォルトでネットワークからの画像の読み込みをサポートしなくなりました。

背景としては以下の2つがあるようです。

  • 利用者が任意のネットワーク・ライブラリを使用できるようにする
  • アプリがネットワーク依存を必要としない場合にネットワークへの依存を追加せずに済むようにする

とはいえ、Coilを使う用途としてはネットワークからの画像読み込みがメインかと思うので、デフォルトで読み込みができなくなるは大きな変更と言えそうですね。

この変更に対応するにあたり、いくつか修正を加える必要がありました。

依存を新たに追加する

ネットワーク画像の読み込みを有効化するには、新たに依存関係を追加する必要があります。
選択肢として他にもいくつか用意されているので、詳しくはドキュメント[2]をご覧ください🙏

implementation("io.coil-kt.coil3:coil-network-okhttp:3.0.4") 

ImageLoaderでのOkHttpClientの指定方法を修正する

callFactoryでのOkHttpClientでの指定ができなくなり、代わりにcomponents APIを使って指定する形に改めました。

@Provides
@Singleton
fun provideImageLoader(
    okHttpClient: OkHttpClient,
    @ApplicationContext application: Context,
): ImageLoader {
    return ImageLoader.Builder(application)
-       .callFactory(okHttpClient)
+       .components {
+           add(
+               OkHttpNetworkFetcherFactory(
+                   callFactory = okHttpClient
+               )
+           )
+       }
        .build()
}

Coilの初期化部分を修正する

Coilの初期化にあたり、これまではCoil.setImageLoaderを使っていたのですが、こちらも3系になったことで廃止されました。
代わりにSingletonImageLoader.setSafeを使用するようにしました。

-    Coil.setImageLoader(
+    SingletonImageLoader.setSafe {

その他

これまでの内容でおおよそ3系への移行は完了しているかと思います。
一方、他にも細かな修正が必要になったところがあったので、簡単に紹介しておきます。

ImageResultのAPI変更に対応する

drawableではなく、imageを使う必要があります。

val bitmap = context.imageLoader
    .executeBlocking(ImageRequest.Builder(context).data(notificationRequest.imageUrl).build())
-   .drawable
+   .image
    ?.toBitmap()

GifのAPI変更に対応する

一部の機能でGif画像の表示機能を使っているのですが、3系に上げたタイミングでDecoderの指定方法を以下のように変更しました。

val imageLoader = ImageLoader.Builder(context)
    .components {
-       add(ImageDecoderDecoder.Factory())
+       add(GifDecoder.Factory())
    }
    .build()

終わりに

ライブラリのアップデートはいつもバージョン更新をして軽く動作確認するくらいで完了していましたが、久しぶりに大きなAPI変更があるアップデートでした。

3系で新しく追加されたLocalAsyncImagePreviewHandler[3]をまだ試せていないので、また時間のある時に使ってみようと思います。

脚注
  1. https://coil-kt.github.io/coil/upgrading_to_coil3/ ↩︎

  2. https://coil-kt.github.io/coil/network/ ↩︎

  3. https://coil-kt.github.io/coil/compose/#previews ↩︎

dely Tech Blog

Discussion