はじめに
本記事は、Androidの壁紙を自動で切り替えるアプリ「壁紙キリカエ」の開発記録です。Next.js (TypeScript) + Kotlin のアーキテクチャを採用し、モダンで拡張性の高いアプリを目指します。
この記事では、Phase 0: 環境構築の過程で遭遇した問題と解決方法を記録しています。
筆者がフロントエンドの開発経験はありますがKotlinは初心者レベルです。
筆者のようなKotlin初心者にも理解しやすいように説明も加えています。(そのため記事が非常に長いです。。)
対象読者
- Androidアプリ開発の初心者〜中級者
- フロントエンド領域の開発経験のある方
- AI アシスタント(Claude など)を活用した開発に興味がある方
開発環境
| 項目 | バージョン |
|---|---|
| OS | macOS |
| IDE | Android Studio (最新版) |
| Kotlin | 1.9+ |
| TypeScript | 5.0+ |
| Next.js | 14+ |
| Android SDK | 26+ (Android 8.0+) |
| 補助ツール | Claude, Claude Code |
プロジェクト概要
アプリ開発の経緯
筆者が使っているAndroid OSのスマホには壁紙を自動で変更できる機能がデフォルトで備わってないので壁紙変更アプリを使っています。
その壁紙変更アプリを使うと、自動で複数の壁紙が変更されるようになります。
しかし使っている壁紙変更アプリは以下のデメリットがあり少々使いづらいものでした。
- 英語表記でしかなく日本人フレンドリーではない
- UIが良くなく慣れるまで使い辛い
なら自分好みのアプリを作ってしまおう。ついでに同じように思っている人たちに使ってもらおう。
と思い似た特徴を持つ自分好みのアプリを日本語版で開発することにしました。
技術選定の背景
なぜNext.js+ Kotlinのアーキテクチャなのか?
本アプリでは、Next.js (WebView) + Kotlin (Native) のアーキテクチャを採用しました。
筆者はNativeアプリ開発が初めてでKotlinは初心者レベルです。Kotlinでも十分にUIも開発できますが、Next.jsの方が使い慣れていたのでUIの開発にはNext.jsを採用しました。
ですがNext.jsだけではスマホの壁紙を設定するなどAndoroidのコアモジュールの接続ができません。そこでAndroidのコアモジュールへの接続にはKotlinを使っています。
Next.jsとKotlinの棲み分け
1. Next.jsでUI層の開発
- Next.js + TypeScript で型安全な開発
- shadcn/ui で手軽に綺麗なコンポーネントを使用
2. Kotlinでロジック層の開発
- 壁紙変更、WorkManager、Room Database などは Kotlin で実装
- Android の標準APIを直接使用できる
- パフォーマンスが重要な部分はネイティブで
Phase 0: 環境構築の目標
Phase 0 では、開発を開始するための基盤を整えます。
完了条件
- Android Studio プロジェクトの作成
- Next.js プロジェクトの作成
- 必要な依存関係のインストール
- WebView で Next.js アプリを表示
- エミュレータでアプリが起動する
タスク一覧
- Android プロジェクトの作成
- 依存関係の追加 (Hilt, Room, DataStore, WorkManager, Serialization)
- プロジェクト構造の作成
- Hilt (DI) の設定
- Next.js プロジェクトの作成
- Next.js のビルド設定
- WebView の統合
- 動作確認
実装手順
1. Android プロジェクトの作成
1-1. Android Studio で新規プロジェクト作成
Android StudioにあるEmpty Activityのテンプレートを使ってプロジェクトを作成しました。
設定値:
| 項目 | 値 |
|---|---|
| Name | 壁紙キリカエ |
| Package name | com.kabegamikirikae.app |
| Language | Kotlin |
| Minimum SDK | API 26 (Android 8.0) |
1-2. プロジェクト構造の確認
作成されたプロジェクト構造:
android/
├── app/
│ ├── src/main/
│ │ ├── java/com/kabegamikirikae/app/
│ │ │ └── MainActivity.kt
│ │ ├── res/
│ │ └── AndroidManifest.xml
│ └── build.gradle.kts
└── build.gradle.kts
2. 依存関係の追加
Android プロジェクトでは、build.gradle.kts というファイルで依存関係を管理します。Node.js の package.json に相当するものです。
プロジェクトレベルとアプリレベルでそれぞれに設定します。
Node.jsで言えば、モノレポのルートに設定するpackage.json(プロジェクト全体の設定を管理)と各パッケージに設定するpackage.json(アプリ固有の設定を管理)に分けるイメージです。
本プロジェクトでは、以下のプラグインとライブラリを追加しています。
追加するプラグイン一覧
| プラグイン / ライブラリ | 種別 | 目的 |
|---|---|---|
com.google.dagger.hilt.android |
Gradle プラグイン | 依存性注入 (DI) フレームワーク。クラス間の依存関係を自動で解決し、テスト容易性と保守性を向上させる |
org.jetbrains.kotlin.plugin.serialization |
Gradle プラグイン | Kotlin の JSON シリアライズ/デシリアライズ をコンパイル時に生成。Next.jsとKotlin間を繋ぐBridge 通信でのデータ変換に使用 |
kotlin-kapt |
Gradle プラグイン | Kotlin の アノテーションプロセッサ。Hilt や Room がコンパイル時にコードを自動生成するために必要 |
追加するライブラリ一覧
| ライブラリ | 目的 |
|---|---|
Hilt (hilt-android, hilt-compiler) |
DI コンテナ。@Inject や @AndroidEntryPoint で依存関係を自動注入するために使用 |
Room (room-runtime, room-ktx, room-compiler) |
ローカルデータベース。壁紙の設定情報やフォルダ情報の永続化に使用 |
DataStore (datastore-preferences) |
ユーザーの 設定値(変更間隔、テーマなど)を非同期・型安全に保存する |
WorkManager (work-runtime-ktx) |
バックグラウンドタスク のスケジューリング。壁紙の自動変更を確実に実行するために使用 |
Kotlinx Serialization (kotlinx-serialization-json) |
Kotlin オブジェクトと JSON の相互変換。WebView ↔ Kotlin の Bridge 通信 でデータをやり取りする際に使用 |
Coroutines (kotlinx-coroutines-android) |
Kotlin の 非同期処理 ライブラリ。Room や DataStore の操作、ネットワーク通信などを非同期で実行 |
AndroidX WebKit (webkit) |
WebView の拡張ライブラリ。標準 WebView よりも多くの機能(ダークモード対応、プロキシ設定など)を提供 |
2-1. プロジェクトレベルの build.gradle.kts
まず android/build.gradle.kts(プロジェクトレベル)に、Hilt と Kotlin Serialization のプラグインを apply false で宣言します。これはプラグインのバージョンを一元管理するためで、実際の適用は各モジュール側で行います。
2-2. アプリレベルの build.gradle.kts
次に android/app/build.gradle.kts(アプリレベル)で、プラグインの適用とライブラリの追加を行います。
コード中のキーワード:
-
implementation— アプリ実行時に使うライブラリ -
kapt— コンパイル時にコードを自動生成するライブラリ(Hilt や Room が該当) -
testImplementation— テスト時のみ使うライブラリ
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
id("kotlin-kapt")
id("com.google.dagger.hilt.android")
id("org.jetbrains.kotlin.plugin.serialization")
}
android {
namespace = "com.kabegamikirikae.app"
compileSdk = 36
defaultConfig {
applicationId = "com.kabegamikirikae.app"
minSdk = 26
targetSdk = 36
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildFeatures {
buildConfig = true // BuildConfig を有効化
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
}
dependencies {
// AndroidX Core
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
// Hilt (Dependency Injection)
implementation("com.google.dagger:hilt-android:2.48")
kapt("com.google.dagger:hilt-compiler:2.48")
// Room (Database)
implementation("androidx.room:room-runtime:2.6.1")
implementation("androidx.room:room-ktx:2.6.1")
kapt("androidx.room:room-compiler:2.6.1")
// DataStore (Settings)
implementation("androidx.datastore:datastore-preferences:1.0.0")
// WorkManager (Background tasks)
implementation("androidx.work:work-runtime-ktx:2.9.0")
// Kotlinx Serialization (JSON)
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
// Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
// WebView
implementation("androidx.webkit:webkit:1.9.0")
// Testing
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
}
3. プロジェクト構造の作成
3-1. パッケージ構造
以下のパッケージ構造を作成します。「UI」「ビジネスロジック」「データ操作」を分離します。
app/src/main/java/com/kabegamikirikae/app/
├── MainActivity.kt … アプリの入口。WebViewを表示する画面
├── KabegamiApplication.kt … アプリ全体の初期化処理(Hiltの起点)
│
├── bridge/ … WebView(TypeScript) ↔ Kotlin の通信層
│ ├── BridgeInterface.kt … JavaScriptから呼び出せる関数を定義
│ ├── EventEmitter.kt … Kotlin → JavaScript へイベントを送る仕組み
│ └── WebViewBridge.kt … 通信全体を管理するクラス
│
├── domain/ … ビジネスロジック(アプリの「ルール」)
│ ├── model/ … データの型定義(壁紙、フォルダなど)
│ ├── repository/ … データ操作のインターフェース(契約書)
│ └── usecase/ … 具体的な処理(「壁紙を変更する」など)
│
├── data/ … データの実際の保存・取得処理
│ ├── local/
│ │ ├── database/ … Room データベースの定義
│ │ ├── datastore/ … ユーザー設定の保存(変更間隔など)
│ │ └── dao/ … DB へのクエリ(データの読み書き操作)
│ ├── repository/ … domain/repository の実装(実際の処理)
│ └── service/ … 壁紙変更などの Android API を呼ぶ処理
│
├── worker/ … バックグラウンド処理(WorkManager)
│ アプリを閉じても壁紙を自動変更する処理
│
└── di/ … 依存性注入(Hilt)の設定
├── AppModule.kt … アプリ全体で使う部品の登録
├── DatabaseModule.kt … DB 関連の部品の登録
└── RepositoryModule.kt … Repository 関連の部品の登録
Node.js の一般的なプロジェクト構造に置き換えると、以下のような対応関係になります。
| Android のディレクトリ | Node.js で例えると |
|---|---|
bridge/ |
API ルーター(Express の routes/) |
domain/model/ |
TypeScript の型定義(types/) |
domain/usecase/ |
サービス層(services/) |
domain/repository/ |
リポジトリのインターフェース |
data/ |
実際の DB 操作(Prisma、TypeORM など) |
worker/ |
バックグラウンドジョブ(Bull、cron) |
di/ |
DI コンテナの設定(NestJS の module) |
3-2. KabegamiApplication.kt の作成
Hilt(DI フレームワーク)を使うには、Application クラスに @HiltAndroidApp アノテーションを付ける必要があります。これがアプリ全体の DI の起点となり、各クラスへの依存性の自動注入が有効になります。
package com.kabegamikirikae.app
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class KabegamiApplication : Application() {
override fun onCreate() {
super.onCreate()
// 初期化処理
}
}
4. Hilt の設定
Hilt は Android 用の依存関係インジェクション ライブラリです。これを使うことで、プロジェクトで依存関係の注入(DI)を手動で行うためのボイラープレートが減ります。(参考)
4-1. AndroidManifest.xml の更新
AndroidManifest.xml は、Android アプリの「設定ファイル」です。このファイルではアプリの基本情報や必要な権限、画面(Activity)の登録などを宣言します。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 権限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<application
android:name=".KabegamiApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.壁紙キリカエ">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
各権限の役割は以下の通りです。
| 権限 | 用途 |
|---|---|
INTERNET |
WebView で Next.js のアセットを読み込むため |
READ_MEDIA_IMAGES |
ユーザーの端末から壁紙用の画像を読み取るため |
POST_NOTIFICATIONS |
壁紙変更の通知をユーザーに表示するため |
SET_WALLPAPER |
端末の壁紙を変更するため |
ポイント:
-
android:name=".KabegamiApplication"— 3-2 で作成した Application クラスを指定。これがないと Hilt の DI が動作しない -
android:exported="true"— ホーム画面のランチャーからアプリを起動可能にする設定 -
intent-filter内のMAIN+LAUNCHER— この Activity がアプリの起動画面であることを OS に伝える
5. MainActivity の実装
5-1. WebView 統合
package com.kabegamikirikae.app
import android.os.Bundle
import android.webkit.WebView
import androidx.appcompat.app.AppCompatActivity
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private lateinit var webView: WebView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
webView = WebView(this).apply {
settings.apply {
javaScriptEnabled = true
domStorageEnabled = true
allowFileAccess = true
allowContentAccess = true
}
// デバッグ用
if (BuildConfig.DEBUG) {
WebView.setWebContentsDebuggingEnabled(true)
}
// アセットからHTMLを読み込み
loadUrl("file:///android_asset/webapp/index.html")
}
setContentView(webView)
}
override fun onBackPressed() {
if (webView.canGoBack()) {
webView.goBack()
} else {
super.onBackPressed()
}
}
}
ポイント:
-
@AndroidEntryPointで Hilt の DI を有効化 -
javaScriptEnabled = trueで JavaScript を有効化 - デバッグ時は Chrome DevTools でデバッグ可能
- 戻るボタンで WebView の履歴を戻る
6. Next.js プロジェクトの作成
6-1. プロジェクトの初期化
UIライブラリにはAIフレンドリーなtailwind cssとshadcn-uiを採用します。
cd ~/Projects/kabegami-kirikae
# Next.js プロジェクトを作成
npx create-next-app@latest webapp \
--typescript \
--tailwind \
--app \
--no-src-dir \
--import-alias "@/*"
cd webapp
# 追加パッケージのインストール
npm install zustand @tanstack/react-query lucide-react
# shadcn/ui のセットアップ
npx shadcn-ui@latest init -y
6-2. Next.js のビルド設定
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
distDir: 'out',
assetPrefix: './',
images: {
unoptimized: true,
},
trailingSlash: true,
}
module.exports = nextConfig
重要な設定:
-
output: 'export'で静的エクスポート -
assetPrefix: './'で相対パス指定 -
images: { unoptimized: true }で画像最適化を無効化(WebView 用)
6-3. ビルドスクリプトの追加
webapp/package.json の scripts セクションに追加します。
{
"scripts": {
"dev": "next dev",
"build": "next build",
"build:android": "next build && node scripts/copy-to-android.js",
"start": "next start",
"lint": "next lint"
}
}
6-4. Android へのコピースクリプト
Next.jsでビルドしたファイルをAndroidでWebview表示するために、ビルド後のファイルをAndoroidへコピーするスクリプトを用意しました。
const fs = require('fs-extra');
const path = require('path');
const source = path.join(__dirname, '../out');
const dest = path.join(__dirname, '../../android/app/src/main/assets/webapp');
console.log('📦 Copying Next.js build to Android assets...');
console.log(`Source: ${source}`);
console.log(`Destination: ${dest}`);
try {
// 既存のディレクトリを削除
if (fs.existsSync(dest)) {
fs.removeSync(dest);
console.log('🗑️ Removed old webapp directory');
}
// コピー
fs.copySync(source, dest);
console.log('✅ Successfully copied Next.js build to Android assets!');
} catch (error) {
console.error('❌ Error copying files:', error);
process.exit(1);
}
7. Next.js の基本ページ作成
7-1. ホーム画面
export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-center p-8">
<div className="text-center">
<h1 className="text-4xl font-bold mb-4">
壁紙キリカエ
</h1>
<p className="text-xl text-gray-600 mb-8">
Kabegami Kirikae
</p>
<div className="bg-gradient-to-r from-indigo-500 to-purple-500 text-white px-6 py-3 rounded-lg">
Phase 0: 環境構築完了!🎉
</div>
</div>
</main>
)
}
7-2. レイアウト
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import './globals.css'
const inter = Inter({ subsets: ['latin'] })
export const metadata: Metadata = {
title: '壁紙キリカエ',
description: 'お気に入りの画像を自動で壁紙に',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="ja">
<body className={inter.className}>{children}</body>
</html>
)
}
8. ビルドと実行
8-1. Next.js のビルド
ビルドからAndroidプロジェクト配下へのコピーまでを行うスクリプト(npm run build:android)を実行します。
cd ~/Projects/kabegami-kirikae/webapp
npm run build:android
8-2. Android アプリの実行
- Android Studio で Sync Project with Gradle Files
- Build > Rebuild Project
- エミュレータを起動
遭遇したエラーと解決方法
Phase 0 の実装中に遭遇したエラーとその解決方法を記載します。
エラー1: compileSdk のバージョン不一致
エラー内容
Dependency 'androidx.core:core:1.17.0' requires libraries and applications that
depend on it to compile against version 36 or later of the Android APIs.
:app is currently compiled against android-34.
原因
AndroidX の最新版(androidx.core 1.17.0)が Android API 36 を要求していたが、プロジェクトはバージョン違いの API 34 でコンパイルしていた。
解決方法
android/app/build.gradle.kts の compileSdk と targetSdk を更新しました:
android {
- compileSdk = 34
+ compileSdk = 36
defaultConfig {
- targetSdk = 34
+ targetSdk = 36
}
}
補足
| 項目 | 説明 |
|---|---|
compileSdk |
コンパイルに使用する Android API バージョン |
targetSdk |
アプリが対象とする Android API バージョン |
minSdk = 26 |
アプリがインストール可能な最低バージョン |
compileSdk を上げても minSdk は変わらないため、古いデバイスでも動作します。
エラー2: Jetpack Compose のコンパイルエラー
エラー内容
e: Backend Internal error: Exception during IR lowering
File being compiled: .../ui/theme/Theme.kt
Caused by: java.lang.IllegalStateException: Unresolved annotation type: [Error type: Unresolved type for Composable]
原因
Android Studio の Empty Activity テンプレートが、デフォルトで Jetpack Compose のファイルを生成していた:
ui/theme/Theme.ktui/theme/Color.ktui/theme/Type.kt
しかし、このプロジェクトでは WebView を使用するため Compose は不要だったので削除することにします。
解決方法
Compose 関連ファイルを削除する。ついでにbuild.gradle.kts から Compose 設定を削除する
削除する項目:
buildFeatures {
compose = true // 削除
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.1" // 削除
}
// dependencies内のCompose関連も削除
エラー3: BuildConfig が見つからない
エラー内容
e: Unresolved reference 'BuildConfig'.
MainActivity.kt の以下の行でエラー:
if (BuildConfig.DEBUG) {
WebView.setWebContentsDebuggingEnabled(true)
}
原因
Android Gradle Plugin 8.0 以降、BuildConfig はデフォルトで生成されなくなったにも関わらずBuildConfigを使おうとしていた
解決方法
android/app/build.gradle.kts に buildFeatures を追加:
android {
// ...
buildFeatures {
buildConfig = true // BuildConfig を有効化
}
// ...
}
補足
BuildConfig クラスは、ビルドタイプ(Debug/Release)やバージョン情報などを含む自動生成クラスになります。有効化することで:
-
BuildConfig.DEBUG: デバッグビルドかどうか -
BuildConfig.VERSION_NAME: バージョン名 -
BuildConfig.APPLICATION_ID: パッケージ名
などが使用できます。
エラー4: AppCompat テーマエラー
エラー内容
java.lang.RuntimeException: Unable to start activity
Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
原因
MainActivity が AppCompatActivity を継承しているのに、themes.xml で Theme.Material を使用していた。
元の themes.xml:
<style name="Theme.壁紙キリカエ" parent="android:Theme.Material.Light.NoActionBar" />
解決方法
android/app/src/main/res/values/themes.xml を修正してMaterialではなくAppCompatを使うようにする:
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <style name="Theme.壁紙キリカエ" parent="Theme.AppCompat.Light.NoActionBar">
+ <style name="Theme.壁紙キリカエ" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryDark">@color/purple_700</item>
<item name="colorAccent">@color/teal_200</item>
</style>
</resources>
AppCompatActivity を使う場合、テーマは Theme.AppCompat の派生である必要があります。
完成した構成
Phase 0 完了時のプロジェクト構造:
kabegami-kirikae/
├── android/
│ ├── app/
│ │ ├── src/main/
│ │ │ ├── java/com/kabegamikirikae/app/
│ │ │ │ ├── MainActivity.kt
│ │ │ │ ├── KabegamiApplication.kt
│ │ │ │ ├── bridge/
│ │ │ │ ├── di/
│ │ │ │ ├── domain/
│ │ │ │ ├── data/
│ │ │ │ └── worker/
│ │ │ ├── res/
│ │ │ │ ├── values/
│ │ │ │ │ ├── colors.xml
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── themes.xml
│ │ │ │ └── mipmap/
│ │ │ ├── assets/
│ │ │ │ └── webapp/ ← Next.jsビルド成果物
│ │ │ └── AndroidManifest.xml
│ │ └── build.gradle.kts
│ └── build.gradle.kts
│
├── webapp/
│ ├── app/
│ │ ├── page.tsx
│ │ ├── layout.tsx
│ │ └── globals.css
│ ├── scripts/
│ │ └── copy-to-android.js
│ ├── next.config.js
│ └── package.json
│
└── docs/
└── (設計ドキュメント)
動作確認
エミュレータでの表示
アプリを起動すると、以下の画面が表示されます。
Chrome DevTools でのデバッグ
WebView のデバッグもできます:
- Chromeで
chrome://inspectを開く - 接続されているデバイスに「壁紙キリカエ」が表示される
- inspect をクリック
- Chrome DevTools が開き、要素の検証やコンソール確認が可能
次のステップ
Phase 0 が完了したので、次は Phase 1: Bridge 実装 (作成中)に進みます。
Phase 1 の目標
- TypeScript ↔ Kotlin 間の通信基盤を構築
- JavascriptInterface の実装
- Bridge Client の実装
- 型安全な通信の確立
予定している機能
-
ping()メソッドで疎通確認 - Kotlin から TypeScript へのイベント送信
- エラーハンドリングの実装
学んだこと
Phase 0 を通じて学んだことをまとめます。
1. AI アシスタントの効果的な活用
今回はAndroidの開発内容を理解するために半分手動・半分自動で開発しました。Claudeを使って実装方法を検討して対話しながら仕様書を作成し、Claude Codeで開発しました。
Claude の使い方:
- 設計段階での相談
- エラーメッセージの診断
- コードレビュー
- ドキュメント作成
Claude Code の使い方:
- プロジェクト構造の自動生成
- 依存関係の一括設定
- 複数ファイルの同時編集
ClaudeとClaude Codeを使い分ける利点:
- 自動化できる部分は Claude Code に任せられる
- 重要な判断はClaudeで相談しながら進められる
- 効率と理解のバランスが取れる
エラーが見つかった場合も、Claude Codeで何となく解消するのではなく、Claudeと会話しながらエラーへの対処方法を検討しエラーの解消を行いました。
しかし、これらはすべてClaude Code側だけでできることなので、ClaudeとClaude Codeを使い分ける必要はないかなと思いました。
2. 設計ドキュメントの重要性
Phase 0 を始める前に詳細な設計ドキュメントを作成したことで:
- 迷わず実装できた
- エラーが出ても方針がブレなかった
- Claude, Claude Codeへの指示が的確になった
まとめ
Phase 0 では、開発環境の構築と WebView での Next.js 表示までを完了しました。
達成したこと
- ✅ Android プロジェクトの作成
- ✅ 必要な依存関係のインストール
- ✅ Hilt (DI) の設定
- ✅ Next.js プロジェクトの作成
- ✅ ビルドスクリプトの作成
- ✅ WebView での表示確認
- ✅ 各種エラーの解決