【ReactNative】Android 15(SDK 35) へのアップグレード

ReactNative Android15アップデート ReactNative

はじめに

毎年恒例のこの行事。

おそらく今年も8月辺りにupdate要件が上がってくると思われるので先に対応した時に、解決までに時間がかかったエラーがあったので残します。

筆者の環境

npx react-native info

System:
  OS: macOS 15.2
  CPU: (8) arm64 Apple M2
  Memory: 227.38 MB / 24.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 18.0.0
    path: ~/.nodenv/versions/18.0.0/bin/node
  Yarn:
    version: 1.22.22
    path: ~/.nodenv/versions/18.0.0/bin/yarn
  npm:
    version: 8.6.0
    path: ~/.nodenv/versions/18.0.0/bin/npm
  Watchman:
    version: 2024.08.26.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.15.2
    path: /Users/sanoasami_1/.rbenv/shims/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.2
      - iOS 18.2
      - macOS 15.2
      - tvOS 18.2
      - visionOS 2.2
      - watchOS 11.2
  Android SDK:
    API Levels:
      - "27"
      - "28"
      - "30"
      - "31"
      - "33"
      - "34"
      - "35"
    Build Tools:
      - 29.0.2
      - 30.0.3
      - 31.0.0
      - 33.0.0
      - 33.0.1
      - 34.0.0
      - 35.0.0
    System Images:
      - android-30 | Google APIs Intel x86 Atom
      - android-33 | ARM 64 v8a
      - android-33 | Intel x86_64 Atom
      - android-33 | Google TV ARM 64 v8a
      - android-33 | Google APIs ARM 64 v8a
      - android-33 | Google Play ARM 64 v8a
      - android-33 | Google APIs ATD ARM 64 v8a
      - android-34 | AOSP ATD ARM 64 v8a
      - android-34 | ARM 64 v8a
      - android-34 | Google APIs ARM 64 v8a
      - android-34 | Google Play ARM 64 v8a
      - android-35 | AOSP ATD ARM 64
      - android-35 | ARM 64 v8a
      - android-35 | Google APIs ARM 64 v8a
      - android-35 | Google Play ARM 64 v8a
    Android NDK: Not Found
IDEs:
  Android Studio: 2022.2 AI-222.4459.24.2221.10121639
  Xcode:
    version: 16.2/16C5032a
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.12
    path: /Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home/bin/javac
  Ruby:
    version: 2.6.10
    path: /Users/sanoasami_1/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.73.9
    wanted: 0.73.9
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: true
  newArchEnabled: false

アップデート手順

android/build.gradletargetSdkVersion/compileSdkVersion と紐づく情報をあげる

targetSdkVersion = 35
compileSdkVersion = 35

// ここら辺は環境に合わせてあげてください。
minSdkVersion = 23
buildToolsVersion = "35.0.0"

ここまではいつも通りですね。

あとは出てきたエラーを潰していって普通にビルド通るところまで持って行き、動作確認を行なっていたところ・・・・

Android12/15では問題なく動いていたので安心していたところ・・・・

Android14だけスクロールしようとしたらクラッシュしてしまいました。

エラー内容

What went wrong: Execution failed for task ':react-native-gesture-handler:compileDebugKotlin'.

A failure occurred while executing org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction Compilation error. See log for more details

react-native-gesture-handlerが何か問題っぽい・・・・?

調べるも解決できそうな記事に出会えませんでしたが、Android15で結構動作に影響がある変更が入ることがわかりました。

動作の変更点: すべてのアプリ  |  Android Developers
すべてのアプリに影響する Android 15 の変更をご確認ください。

Android15がリリースされてから1年以上経っているのでreact-native-gesture-handlerライブラリをアップデートしたら解決するかと思いきや、筆者は解決しませんでした。

解決策

① パッチを当てる

このエラーは、java.util.ArrayListクラスにreversed()メソッドが存在しないために発生しています。

よってreversed()メソッドを使用する代わりに、Kotlinの標準ライブラリを使用してリストを逆順にする方法を適用します。具体的には、asReversed()メソッドを使用します。

~/node_modules/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt

に対してreversed()をasReversed()に置換して行きます。

patch-packageが入っていることが前提です。

パッチの内容はこんな感じになりました。

diff --git a/node_modules/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt b/node_modules/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt
index 3c5e5ea..bf61df6 100644
--- a/node_modules/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt
+++ b/node_modules/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt
@@ -190,7 +190,7 @@ class GestureHandlerOrchestrator(
     }

     // Clear all awaiting handlers waiting for the current handler to fail
-    for (otherHandler in awaitingHandlers.reversed()) {
+    for (otherHandler in awaitingHandlers.asReversed()) {
       if (shouldHandlerBeCancelledBy(otherHandler, handler)) {
         otherHandler.isAwaiting = false
       }
@@ -236,7 +236,7 @@ class GestureHandlerOrchestrator(
   }

   private fun cancelAll() {
-    for (handler in awaitingHandlers.reversed()) {
+    for (handler in awaitingHandlers.asReversed()) {
       handler.cancel()
     }
     // Copy handlers to "prepared handlers" array, because the list of active handlers can change
@@ -244,7 +244,7 @@ class GestureHandlerOrchestrator(
     preparedHandlers.clear()
     preparedHandlers.addAll(gestureHandlers)

-    for (handler in gestureHandlers.reversed()) {
+    for (handler in gestureHandlers.asReversed()) {
       handler.cancel()
     }
   }

これでビルドし直したらAndroid14でもスクロールできるようになりました。

コメント