プロダクション環境の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をホストするためだけに FragmentActivity や NavHostFragment を使う必要はありません。
メインのエントリーポイントは、シンプルな 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)のためのブリッジコードを削除する
移行期間中、ComposeView や AndroidView といった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 : Android・Developmemt・JetpackCompose・KMP・Kotlin・Kotlin Multiplatform Mobile・Recommended