Jetpack Compose 移行完了チェック:旧 AndroidView システムを安全に完全削除できたか確認する

プロダクション環境のAndroidアプリを Jetpack Compose へ移行する作業は、一朝一夕で完了するものではありません。

中〜大規模のコードベースでは、移行は段階的に進むのが一般的です。そのため、XMLレイアウト、ComposeView、AndroidView が、モダンなComposableと数ヶ月〜数年にわたって共存することになります。

段階的な移行は最も安全なアプローチです。しかし、移行が完了したあとも古いインフラを残したままにしておくと、無駄な複雑さが増すだけになってしまいます。

ここで生まれるのが、

「本当に移行が完了したと、どうやって判断すればいいのか?」

という疑問です。

この記事では、アプリから旧Viewシステムのコードを安全に削除し、完全移行を果たすための実践的なチェック方法を紹介します。

 

🧑🏻‍💻 ビルド設定(buildFeatures)をオフにする

まずは一番わかりやすいビルド設定から見直しましょう。

View Binding や Data Binding なしでビルドできれば、旧Viewシステムへの大きな依存を断ち切れた証拠になります。

モジュールレベルの build.gradle.kts を確認・修正します。


android {
    // ...

    buildFeatures {
        compose = true

        viewBinding = false
        dataBinding = false
    }
}

続いて、依存関係を見直し、不要になったライブラリを削除します。


dependencies {
    // 不要になった旧Viewシステムの依存関係を削除

    // implementation("com.google.android.material:compose-theme-adapter:...")
    // implementation("androidx.appcompat:appcompat:...")
    // implementation("androidx.constraintlayout:constraintlayout:...")
    // implementation("androidx.navigation:navigation-fragment-ktx:...")
    // implementation("androidx.navigation:navigation-ui-ktx:...")
}

 

🧑🏻‍💻 エントリーポイントを Compose 単一にする

完全移行したアプリでは、UIをホストするためだけに FragmentActivityNavHostFragment を使う必要はありません。

メインのエントリーポイントは、シンプルな ComponentActivity で十分です。


class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            AppTheme {
                AppNavigation()
            }
        }
    }
}

もちろん、以下のようなコードは完全に不要になります。


// 不要!
setContentView(R.layout.activity_main)

Activityは、XMLレイアウトのコンテナではなく、Compose UIへのエントリーポイントとして機能するようになります。

 

🧑🏻‍💻 相互運用(Interop)のためのブリッジコードを削除する

移行期間中、ComposeViewAndroidView といったAPIは非常に強力な味方でした。これらのおかげで、View システムとCompose の境界線を段階的にまたぐことができたからです。

しかし、移行が終わったのであれば、これらの「架け橋」は役目を終えています。

プロジェクト全体で以下を検索してみてください。

- ComposeView

- AndroidView

- androidx.fragment.app.Fragment

目指すべき残存数は「0」です。

例えば、以下のようなコードは存在しなくなるはずです。


// これらはもう不要
val composeView = ComposeView(context).apply {
    setContent {
        MainScreen()
    }
}

また、こちらも同様です。


// これらも不要
AndroidView(
    factory = { context ->
        CustomLegacyView(context)
    }
)

重要な考え方はシンプルです。

「相互運用(Interop)は足場であって、目的地ではない」 ということです。

 

🧑🏻‍💻 デザインシステムを Compose 純正にする

完全移行したアプリでは、デザイントークンをKotlinコード内で直接定義できます。


@Composable
fun AppTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    val colorScheme =
        if (darkTheme) DarkColorScheme
        else LightColorScheme

    MaterialTheme(
        colorScheme = colorScheme,
        typography = AppTypography,
        shapes = AppShapes,
        content = content
    )
}

カラー、タイポグラフィ、シェイプなどを Compose に適用するためだけに、res/values/styles.xml を参照する必要はもうありません。

UIテクノロジーと信頼できる唯一の情報源(Source of Truth)が同じ Kotlin コード上に並ぶため、デザインシステムの保守性・見通しが大幅に向上します。

 

🧑🏻‍💻 ナビゲーションを宣言型にする

画面遷移(ナビゲーション)についても、XMLの Navigation Graph や Fragment トランザクションから脱却しましょう。

ルート(Route)、引数(Arguments)、画面(Destinations)は、Compose Navigation のセットアップ内で直接管理できます。


@Serializable
data object Home : NavKey

@Serializable
data class Detail(val id: String) : NavKey

@Composable
fun AppNavigation() {
    val backStack = rememberNavBackStack(Home)

    NavDisplay(
        backStack = backStack,
        entryProvider = entryProvider {
            entry<Home> {
                HomeScreen(
                    onOpenDetail = { id ->
                        backStack.add(Detail(id))
                    }
                )
            }

            entry<Detail> { key ->
                DetailScreen(
                    id = key.id
                )
            }
        }
    )
}

ここでの目的は、単に「XMLをKotlinに置き換える」ことではありません。

本質は、Fragmentベースのナビゲーション層を取り払い、UIと同じ「宣言型アーキテクチャ」にナビゲーション構造を一致させることにあります。

 

🧑🏻‍💻 最後にリポジトリ全体を走査する

「移行完了!」と宣言する前に、古いUIシステムを引き戻してしまうようなコードが残っていないか、リポジトリ全体を検索して確認しましょう。

ターミナルで以下のコマンドを実行してみるのがおすすめです。


# 残っているUI用XMLレイアウトのチェック
find app/src/main/res/layout -name "*.xml"

# Compose / View 相互運用コードの検索
grep -rn "ComposeView" app/src/main/java/
grep -rn "AndroidView" app/src/main/java/

# Fragment の使用箇所の検索
grep -rn "androidx.fragment.app.Fragment" app/src/main/java/

理想的な状態は以下の通りです。

・ res/layout にUIレイアウト用のXMLが存在しない

・ ComposeView の使用箇所が 0 である

・ AndroidView の使用箇所が 0 である

・ Fragment ベースの画面が存在しない

・ View Binding および Data Binding が無効化されている

・ テーマがXMLスタイルに依存していない

・ ナビゲーションが Fragment インフラに依存していない

 

🧑🏻‍💻 まとめ

100% Jetpack Compose への移行とは、単に XML ファイルを Composable 関数に書き換えることではありません。

本当のゴールは、「旧 View システムがアプリの UI アーキテクチャから完全に消え去ること」 です。

【移行前】


Activity
 └─ Fragment
     └─ XML
         └─ View
             └─ ComposeView
                 └─ Compose

【移行後】


Activity
 └─ Compose
     ├─ Theme
     ├─ Navigation
     └─ Screens

私たちの目標は、単に「Compose を使っている」と言うことではありません。

「もうViewシステムを必要としない」 状態を作ることこそが、本当のゴールなのです。


Related Categories :  AndroidDevelopmemtJetpackComposeKMPKotlinKotlin Multiplatform MobileRecommended