◉RORK LABEN
●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SDK 58 — Beta が 09/15 から。stable の案内はまだなく、Expo Go でのプロジェクト実行は 09/03 からログインが必要です●WIDGET — iOS のウィジェットが本番ビルドだけ真っ黒になる原因を追った報告が出ています●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SDK 58 — Beta が 09/15 から。stable の案内はまだなく、Expo Go でのプロジェクト実行は 09/03 からログインが必要です●WIDGET — iOS のウィジェットが本番ビルドだけ真っ黒になる原因を追った報告が出ています●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…
記事一覧/開発ツール
⬡ 開発ツール/2026-05-15中級

Rork Max Android アプリが古い OS バージョンだけクラッシュする原因と Java 8 デシュガリング修正

Rork Max で生成した Android アプリが古い OS バージョン(Android 6〜8 など)でのみクラッシュする問題の診断方法と、Java 8 デシュガリング設定による根本解決を解説します。

Rork Max236Android55クラッシュ5Java 8デシュガリングトラブルシューティング85AGP

Beautiful HD Wallpapers の Android 版を v2.1.0 にアップデートした後、Firebase Crashlytics のダッシュボードに見慣れないエラーが積み上がり始めました。

java.lang.NoClassDefFoundError: Failed resolution of: Ljava/util/function/Supplier;

Android 6.0.1 のユーザーだけが再現するこのクラッシュ、端末が古いせいだろうと最初は思いました。しかし原因は別のところにありました。Rork Max が生成するコードには Glide 5.x や AGP 9.x との組み合わせで Java 8 の API がそのまま使われることがあります。Android 8.0 未満の端末はこれをネイティブに処理できないため、特定のユーザー層だけがアプリを起動できない状態になります。

厄介なのは、手元の検証端末では一度も再現しないことです。開発機が新しいほど発見が遅れ、気づいたときには低評価レビューが先に届いています。以下では Crashlytics での切り分けから coreLibraryDesugaringEnabled による恒久対処、そして「設定を入れたのに直らない」ケースまでを順に扱います。

なぜ「特定の OS バージョンだけ」クラッシュするのか

Android はバージョンごとに対応している Java API の範囲が異なります。Java 8 で追加された Stream、Optional、Supplier などのクラスは、Android 8.0(API 26)以上でのみ標準サポートされています。

Rork Max が生成するコードは最新の Android 環境を前提としているため、これらのクラスを使うライブラリ(Glide 5.x など)との組み合わせで、古い OS バージョンで動かないコードが出てくることがあります。

実際にどのクラスが境界線上にあるのかを把握しておくと、クラッシュログを見た瞬間に当たりがつきます。よく踏むものを挙げます。

APIネイティブ対応よく混入する経路
java.util.function.Supplier / ConsumerAPI 24 以上Glide 5.x の内部実装
java.util.stream.StreamAPI 24 以上ユーティリティ系ライブラリ
java.util.OptionalAPI 24 以上Firebase SDK の一部
java.time.*(LocalDate 等)API 26 以上日付処理を自前実装したとき
java.nio.file.*非対応(別ライブラリが必要)ファイル操作の生成コード

スタックトレースの Failed resolution of: の後ろがこの表のどれかに当たるなら、端末固有の不具合ではなくデシュガリング設定の欠落です。

個人開発を続ける中でリリース後 28 日間で 50 件以上の NoClassDefFoundError クラッシュレポートが届き、Crash-free users が 99.4% まで落ちたときは、放置できない数字だと感じました。Play Store の評価に直結する問題です。

Step 1:Firebase Crashlytics でクラッシュを特定する

まず Crashlytics のダッシュボードで、どの端末・OS バージョンでクラッシュが集中しているか確認します。

「Issues」タブでエラーを開くと「Session details」にデバイス情報が表示されます。「Android 6.0.1 / 7.0 が多い」というパターンが見えたら、Java 8 デシュガリング問題の可能性が高いです。

確認するポイントは以下の通りです。

  • OS バージョンが Android 8.0(API 26)未満に集中していないか
  • スタックトレースに NoClassDefFoundError や ClassNotFoundException が出ていないか
  • Glide、OkHttp、Firebase SDK など外部ライブラリが絡んでいないか

Rork Max プロジェクトの場合、Expo の managed workflow から ejected した後の android/app/build.gradle を確認します。

Step 2:app/build.gradle の compileOptions を確認する

Rork Max が生成した Android プロジェクトの android/app/build.gradle を開いてください。

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

sourceCompatibility と targetCompatibility が VERSION_1_8 になっていても、それだけでは Android 8.0 未満の実機での動作は保証されません。デシュガリング(Desugaring) の設定が別途必要です。

デシュガリングとは、Java 8 以上の構文を古い Android でも理解できる形に変換するプロセスです。有効にするには、同じ compileOptions ブロックに1行追加します。

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
        coreLibraryDesugaringEnabled true
    }
}
 
dependencies {
    coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.0.4"
}

この修正を行った後にビルドし直したところ、Android 6.0.1 ユーザーのクラッシュが完全に消えました。v2.1.0 のリリースに間に合わせることができ、ユーザーレビューの星評価の低下も防ぐことができました。

Step 3:Rork の AI に修正を依頼する際のプロンプト

Rork の AI に修正を依頼する際は、具体的なエラーメッセージとファイル名を添えて指示します。漠然と「クラッシュを直して」と伝えても、AI は何を変えればいいか判断できません。

実際に使っている依頼文はこの形です。

android/app/build.gradle の android.compileOptions に
coreLibraryDesugaringEnabled true を追加し、
dependencies に coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:2.0.4" を追加してください。

対象ファイル: android/app/build.gradle のみ
変更しないもの: minSdkVersion、他の依存関係のバージョン
理由: Android 6.0.1 で java.util.function.Supplier が NoClassDefFoundError になるため

修正依頼のポイントは「対象ファイル」「追加する行」「エラーの再現条件」の3点を明示することです。加えて「変更しないもの」を書いておくと精度が上がります。このように変更スコープを限定することで、AI が余計なファイルを書き換えるリスクを減らせます。Rork の AI は親切ですが、スコープを広く与えると関係のないコードまで変えることがあります。

デシュガリングを入れても直らなかった2つのケース

設定を追加したのにクラッシュが残ったことが2度あります。どちらも原因は build.gradle の外側にありました。

1つ目は R8 の縮小との併用です。 minifyEnabled true の状態でデシュガリング後のクラスが難読化の対象になり、リフレクション経由の参照が解決できなくなっていました。proguard-rules.pro に退避ルールを足して解消しています。

-keep class j$.util.** { *; }
-keep class j$.time.** { *; }
-dontwarn java.lang.invoke.**

デシュガリングされたクラスは j$ プレフィックスの下に再配置されるため、java.* を対象にしたルールでは守れません。ここを見落としていました。

2つ目はビルドキャッシュです。 設定を入れた直後のビルドで古い dex がそのまま再利用され、「直したはずなのに再現する」状態になりました。設定を変えた直後は必ずクリーンビルドを挟みます。

cd android && ./gradlew clean
./gradlew assembleRelease --rerun-tasks

もう一点、minSdkVersion を上げて回避する選択肢もあります。ただし Android 6〜7 が残っている地域では想像以上にユーザーを切り捨てることになります。Google Play Console の「Android バージョン」分布を見てから判断してください。私自身のアプリでは API 24 未満が全体の 1.8% で、切り捨てるより設定1行を足すほうが妥当だと判断しました。

Step 4:AGP バージョンと Glide の組み合わせに注意する

AGP(Android Gradle Plugin)9.x と Glide 5.0.x を組み合わせた場合に特にこの問題が出やすいです。Rork Max が生成するプロジェクトはデフォルトで最新の AGP を使いますが、desugar_jdk_libs のバージョンが古い場合も同様のクラッシュが起きます。

desugar_jdk_libs は 2.0.4 以上を使うことを推奨します。古いバージョンでは一部の Java 8 API が正しく変換されないケースがあります。Glide の Kotlin API や Coroutines 統合を使っている場合も同じ設定で対応できます。

Step 5:段階公開でリスクを最小化する

個人開発者にとって、リリース後のクラッシュは評価とユーザー離脱に直結します。Play Store の段階公開(5% → 25% → 50% → 100%)を使うことで、被害を最小限に抑えられます。

個人開発の現場で使っている監視基準は以下の通りです。

  • Crash-free users: 各フェーズで 99.7% 以上をキープする
  • ANR rate: 0.20% 未満をキープする
  • 各フェーズで 24〜48 時間の様子見期間を設ける

5% の段階で Crash-free users が 99.4% に落ちたら、それ以上展開せずに原因を特定します。今回の Java 8 デシュガリング問題は、このプロセスで段階公開の 25% 到達前に発見できました。全ユーザーへの展開前に対処できたことが、評価への影響を最小化できた理由です。

Step 6:リリース前の予防策として古い端末でのテストを組み込む

Rork Max で生成したコードを AGP 9.x や最新ライブラリと組み合わせて使う場合、リリース前に Android 7.0〜8.0 の実機またはエミュレーターでの動作確認を必ず行うことをお勧めします。

個人開発では実機テストの時間が限られるため、私は Android Studio のエミュレーターで API 24(Android 7.0)と API 28(Android 9)の2つを常時用意しています。このテスト環境があるだけで、Java 8 デシュガリング問題の大半はリリース前に発見できます。

テスト手順は以下のような流れです。まず Rork Max でビルドした APK を API 24 エミュレーターにインストールします。次にアプリの主要な画面をひと通り操作し、スタックトレースが出ないことを確認します。最後に API 28 エミュレーターで同じ操作を繰り返し、新旧の OS で動作に差がないことを確認します。

この工程を CI に組み込むのが理想的ですが、個人開発の場合は手動でも十分です。リリース前の 5〜10 分で、リリース後の評価低下リスクを大幅に下げることができます。

Rork の AI でコードを生成するたびに依存ライブラリが変わる可能性があるため、新機能を追加するたびにこの確認を行うことを習慣にするとよいでしょう。

全体を振り返って:Crashlytics の確認から始める

Rork Max で生成した Android アプリが「特定の古い端末だけクラッシュする」という症状のとき、最初にやることは Crashlytics でクラッシュの OS バージョン分布を見ることです。「Android 8.0 未満に集中」していれば、coreLibraryDesugaringEnabled true と desugar_jdk_libs の追加で大半のケースが解決します。

まずは Firebase Crashlytics を Rork Max プロジェクトに設定するところから始めるとよいでしょう。

シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

⬡ 開発ツール2026-10-07
日本語の見出しだけ太字にならない — Android で fontWeight が効かないときの切り分けと直し方
Rork で作ったアプリで、iPhone では太字なのに Android では日本語の見出しが細いままになる症状の切り分け記事です。原因の見分け方、fontFamily を重みごとに分ける直し方、確認用コードを載せています。
⬡ 開発ツール2026-05-01
Rork Max で画面録画と配信を実装する — ReplayKit と MediaProjection の本番運用ガイド
Rork Max のアプリに iOS ReplayKit と Android MediaProjection を統合し、ゲームプレイ録画・チュートリアル動画作成・ライブ配信機能を実装する本番運用ガイド。
⬡ 開発ツール2026-10-15
EXPO_PUBLIC_ の値が、開発では読めて本番だけ undefined になる書き方を、変換結果で見分けます
API の URL が開発中は読めるのに、ビルドした途端に undefined になる。原因は process.env の書き方でした。babel-preset-expo の変換結果を開発・本番で並べ、置き換わる書き方と残ってしまう書き方を表にしました。