安装包含本机代码的包后,我的本机反应应用程序无法在 android 上启动

My react-native application is unable to launch on android after installing a package containing native code

抱歉,如果这个问题有点过于笼统,但我只希望在 react-native 和 Android 方面比我更有经验的人可以帮助我解决这个我现在经常遇到的问题。

事实上,我已经有一段时间无法在我的 react-native 项目中正确安装包含本机代码的包了。我成功安装的最后一个本地包,不是没有很多问题,它是@react-native-community/google-signin(不过,我认为这与这个问题无关)

我之后安装的所有其他软件包在安装后都给我错误,我被迫放弃所有这些。最初我认为这是个别包的问题(事实上,一旦我删除它们,应用程序就会再次开始工作)。当然,我现在有必要的经验来说,这是所有包含原生代码的包所共有的问题。

一开始我也以为可能是yarn workspace的错误,为此为了前期教育,我在nohoist列表中添加了所有包含native代码的包:

"workspaces": {
    "nohoist": [
      "react-native",
      "react-native/**",
      "@react-native-mapbox-gl",
      "@react-native-mapbox-gl/**",
      "react-native-gesture-handler",
      "react-native-gesture-handler/**",
      "react-native-reanimated",
      "react-native-reanimated/**",
      "@react-navigation",
      "@react-navigation/**",
      "react-native-safe-area-context",
      "react-native-safe-area-context/**",
      "react-native-vector-icons",
      "react-native-vector-icons/**",
      "react-native-pose",
      "react-native-pose/**",
      "@react-native-community",
      "@react-native-community/**",
      "react-native-elements",
      "react-native-elements/**",
      "react-native-snackbar",
      "react-native-snackbar/**"
    ]
  }

今天我尝试再安装两个我需要的包:react-native-secure-storage 和 react-native-snackbar;但是我无法安装它们。和其他的一样,通过 yarn 或 npm 安装后,该应用程序不再能够启动。例如,对于包 react-native-snackbar,启动应用程序时出现以下错误:

Task :app:mergeDexDebug FAILED

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.0.1/userguide/command_line_interface.html#sec:command_line_warnings
206 actionable tasks: 191 executed, 15 up-to-date
Note: mydir\packages\mobile\node_modules\@react-native-community\google-signin\android\src\main\java\co\apptailor\googlesignin\RNGoogleSigninModule.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Note: mydir\packages\mobile\node_modules\react-native-gesture-handler\android\src\main\java\com\swmansion\gesturehandler\react\RNGestureHandlerButtonViewManager.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Note: mydir\packages\mobile\node_modules\react-native-reanimated\android\src\main\java\com\swmansion\reanimated\NodesManager.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: mydir\packages\mobile\node_modules\react-native-reanimated\android\src\main\java\com\swmansion\reanimated\NodesManager.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
D8: Cannot fit requested classes in a single dex file (# fields: 68231 > 65536)
com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives:
The number of method references in a .dex file cannot exceed 64K.
Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html
        at com.android.builder.dexing.D8DexArchiveMerger.getExceptionToRethrow(D8DexArchiveMerger.java:131)
        at com.android.builder.dexing.D8DexArchiveMerger.mergeDexArchives(D8DexArchiveMerger.java:118)
        at com.android.build.gradle.internal.transforms.DexMergerTransformCallable.call(DexMergerTransformCallable.java:102)
        at com.android.build.gradle.internal.tasks.DexMergingTaskRunnable.run(DexMergingTask.kt:444)
        at com.android.build.gradle.internal.tasks.Workers$ActionFacade.run(Workers.kt:335)
        at org.gradle.workers.internal.AdapterWorkAction.execute(AdapterWorkAction.java:50)
        at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:50)
        at org.gradle.workers.internal.NoIsolationWorkerFactory.create(NoIsolationWorkerFactory.java:65)
        at org.gradle.workers.internal.NoIsolationWorkerFactory.create(NoIsolationWorkerFactory.java:61)
        at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:98)
        at org.gradle.workers.internal.NoIsolationWorkerFactory.execute(NoIsolationWorkerFactory.java:61)
        at org.gradle.workers.internal.AbstractWorker.call(AbstractWorker.java:44)
        at org.gradle.workers.internal.AbstractWorker.call(AbstractWorker.java:41)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)    
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)    
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:165)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
        at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
        at org.gradle.workers.internal.NoIsolationWorkerFactory.execute(NoIsolationWorkerFactory.java:53)
        at org.gradle.workers.internal.DefaultWorkerExecutor.call(DefaultWorkerExecutor.java:217)
        at org.gradle.workers.internal.DefaultWorkerExecutor.call(DefaultWorkerExecutor.java:212)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:215)
        at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
        at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:131)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
        at org.gradle.internal.concurrent.ManagedExecutorImpl.run(ManagedExecutorImpl.java:48)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
        at java.lang.Thread.run(Thread.java:748)
Caused by: com.android.tools.r8.CompilationFailedException: Compilation failed to complete
        at com.android.tools.r8.utils.t.a(:55)
        at com.android.tools.r8.D8.run(:11)
        at com.android.builder.dexing.D8DexArchiveMerger.mergeDexArchives(D8DexArchiveMerger.java:116)
        ... 34 more
Caused by: com.android.tools.r8.utils.AbortException: Error: null, Cannot fit requested classes in a single dex file (# fields: 68231 > 65536)
        at com.android.tools.r8.utils.Reporter.a(:21)
        at com.android.tools.r8.utils.Reporter.a(:7)
        at com.android.tools.r8.dex.VirtualFile.a(:33)
        at com.android.tools.r8.dex.VirtualFile$h.a(:5)
        at com.android.tools.r8.dex.ApplicationWriter.a(:13)
        at com.android.tools.r8.dex.ApplicationWriter.write(:35)
        at com.android.tools.r8.D8.d(:44)
        at com.android.tools.r8.D8.b(:1)
        at com.android.tools.r8.utils.t.a(:23)
        ... 36 more


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:mergeDexDebug'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
   > com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives:
     The number of method references in a .dex file cannot exceed 64K.
     Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.    

* Get more help at https://help.gradle.org

BUILD FAILED in 40s

error Failed to install the app. Make sure you have the Android development environment set up: https://reactnative.dev/docs/environment-setup. Run CLI 
with --verbose flag for more details.
Error: Command failed: gradlew.bat app:installDebug -PreactNativeDevServerPort=8081
Note: mydir\packages\mobile\node_modules\@react-native-community\google-signin\android\src\main\java\co\apptailor\googlesignin\RNGoogleSigninModule.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Note: mydir\packages\mobile\node_modules\react-native-gesture-handler\android\src\main\java\com\swmansion\gesturehandler\react\RNGestureHandlerButtonViewManager.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Note: mydir\packages\mobile\node_modules\react-native-reanimated\android\src\main\java\com\swmansion\reanimated\NodesManager.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: mydir\packages\mobile\node_modules\react-native-reanimated\android\src\main\java\com\swmansion\reanimated\NodesManager.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
D8: Cannot fit requested classes in a single dex file (# fields: 68231 > 65536)
com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives:
The number of method references in a .dex file cannot exceed 64K.
Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html
        at com.android.builder.dexing.D8DexArchiveMerger.getExceptionToRethrow(D8DexArchiveMerger.java:131)
        at com.android.builder.dexing.D8DexArchiveMerger.mergeDexArchives(D8DexArchiveMerger.java:118)
        at com.android.build.gradle.internal.transforms.DexMergerTransformCallable.call(DexMergerTransformCallable.java:102)
        at com.android.build.gradle.internal.tasks.DexMergingTaskRunnable.run(DexMergingTask.kt:444)
        at com.android.build.gradle.internal.tasks.Workers$ActionFacade.run(Workers.kt:335)
        at org.gradle.workers.internal.AdapterWorkAction.execute(AdapterWorkAction.java:50)
        at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:50)
        at org.gradle.workers.internal.NoIsolationWorkerFactory.create(NoIsolationWorkerFactory.java:65)
        at org.gradle.workers.internal.NoIsolationWorkerFactory.create(NoIsolationWorkerFactory.java:61)
        at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:98)
        at org.gradle.workers.internal.NoIsolationWorkerFactory.execute(NoIsolationWorkerFactory.java:61)
        at org.gradle.workers.internal.AbstractWorker.call(AbstractWorker.java:44)
        at org.gradle.workers.internal.AbstractWorker.call(AbstractWorker.java:41)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)    
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)    
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:165)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
        at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
        at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
        at org.gradle.workers.internal.NoIsolationWorkerFactory.execute(NoIsolationWorkerFactory.java:53)
        at org.gradle.workers.internal.DefaultWorkerExecutor.call(DefaultWorkerExecutor.java:217)
        at org.gradle.workers.internal.DefaultWorkerExecutor.call(DefaultWorkerExecutor.java:212)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:215)
        at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
        at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:131)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
        at org.gradle.internal.concurrent.ManagedExecutorImpl.run(ManagedExecutorImpl.java:48)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
        at java.lang.Thread.run(Thread.java:748)
Caused by: com.android.tools.r8.CompilationFailedException: Compilation failed to complete
        at com.android.tools.r8.utils.t.a(:55)
        at com.android.tools.r8.D8.run(:11)
        at com.android.builder.dexing.D8DexArchiveMerger.mergeDexArchives(D8DexArchiveMerger.java:116)
        ... 34 more
Caused by: com.android.tools.r8.utils.AbortException: Error: null, Cannot fit requested classes in a single dex file (# fields: 68231 > 65536)
        at com.android.tools.r8.utils.Reporter.a(:21)
        at com.android.tools.r8.utils.Reporter.a(:7)
        at com.android.tools.r8.dex.VirtualFile.a(:33)
        at com.android.tools.r8.dex.VirtualFile$h.a(:5)
        at com.android.tools.r8.dex.ApplicationWriter.a(:13)
        at com.android.tools.r8.dex.ApplicationWriter.write(:35)
        at com.android.tools.r8.D8.d(:44)
        at com.android.tools.r8.D8.b(:1)
        at com.android.tools.r8.utils.t.a(:23)
        ... 36 more


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:mergeDexDebug'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
   > com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: 
     The number of method references in a .dex file cannot exceed 64K.
     Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.    

* Get more help at https://help.gradle.org

BUILD FAILED in 40s

    at makeError (mydir\packages\mobile\node_modules\execa\index.js:174:9)
    at mydir\packages\mobile\node_modules\execa\index.js:278:16
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async runOnAllDevices (mydir\packages\mobile\node_modules\@react-native-community\cli-platform-android\build\commands\runAndroid\runOnAllDevices.js:94:5)
    at async Command.handleAction (mydir\packages\mobile\node_modules\@react-native-community\cli\build\index.js:186:9)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

我没有足够的 android 开发经验来理解问题所在,但我认为它很有可能与向 AndroidX 的迁移有关。

在我的项目中,我使用的react-native版本是0.62.2。

您需要在 build.grade 文件中启用 multidexsupport 检查这个