说我花了大约 32 个小时是轻描淡写的。我一直在尝试在由 Expo SDK 44 提供支持的 React Native 项目中启用 Kotlin。
我一直在尝试我在互联网上能找到的一切,但它总是在 EAS 的 Gradle 阶段出现错误(使用 eas build --profile 开发 --platform android
运行它)。
以下是我的配置:
为了简洁起见,我省略了代码。如果您需要更多背景信息,请告诉我
app\android\build.gradle:
buildscript {
ext {
buildToolsVersion = "30.0.2"
minSdkVersion = 21
compileSdkVersion = 31
targetSdkVersion = 31
kotlinVersion = "1.4.11"
}
repositories {
google()
mavenCentral()
jcenter()
}
dependencies {
classpath("com.android.tools.build:gradle:4.1.0")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
apply plugin: "kotlin-android"
apply plugin: "kotlin-android-extensions"
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
implementation project(':react-native-plaid-link-sdk')
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
implementation 'androidx.core:core-ktx:1.1.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion"
// Other comed omitted
}
这是我的包.json
{
"name": "@pana/app",
"version": "22.0220",
"private": true,
"scripts": {
"start": "expo start --dev-client",
"android": "expo run:android",
"ios": "expo run:ios",
"eject": "expo eject",
"extract": "lingui extract",
"compile": "lingui compile",
"lint": "eslint src/** --ext .ts,.tsx",
"lint:fix": "yarn lint --fix",
"test": "jest",
"graphql:generate": "graphql-codegen --config codegen.yml",
"build": ""
},
"dependencies": {
"@apollo/client": "^3.5.10",
"@apollo/link-context": "^2.0.0-beta.3",
"@expo/react-native-action-sheet": "^3.13.0",
"@intercom/intercom-react-native": "^3.0.0",
"@lingui/react": "^3.13.2",
"@onfido/react-native-sdk": "^5.1.0",
"@react-native-async-storage/async-storage": "~1.15.0",
"@react-native-community/datetimepicker": "4.0.0",
"@react-navigation/bottom-tabs": "^6.3.1",
"@react-navigation/native": "^6.0.8",
"@react-navigation/stack": "^6.1.1",
"@reduxjs/toolkit": "^1.8.0",
"@segment/analytics-react-native": "^2.1.12",
"@segment/sovran-react-native": "^0.2.6",
"@sentry/react-native": "^3.2.13",
"axios": "^0.25.0",
"dayjs": "^1.10.8",
"expo": "~44.0.0",
"expo-application": "~4.0.1",
"expo-auth-session": "~3.5.0",
"expo-cellular": "~4.1.0",
"expo-clipboard": "~2.1.0",
"expo-constants": "~13.0.1",
"expo-crypto": "~10.1.1",
"expo-dev-client": "~0.8.5",
"expo-device": "~4.1.0",
"expo-document-picker": "~10.1.3",
"expo-image-loader": "~3.1.0",
"expo-image-picker": "~12.0.2",
"expo-linear-gradient": "~11.0.3",
"expo-local-authentication": "~12.1.0",
"expo-random": "~12.1.1",
"expo-secure-store": "~11.1.0",
"expo-splash-screen": "~0.14.1",
"expo-status-bar": "~1.2.0",
"expo-updates": "~0.11.7",
"make-plural": "^7.1.0",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-animated-progress": "^1.0.2",
"react-native-country-picker-modal": "^2.0.0",
"react-native-dotenv": "^3.3.1",
"react-native-gesture-handler": "~2.1.0",
"react-native-keyboard-aware-scroll-view": "^0.9.5",
"react-native-phone-number-input": "^2.1.0",
"react-native-plaid-link-sdk": "^7.4.0",
"react-native-safe-area-context": "3.3.2",
"react-native-screens": "~3.10.1",
"react-native-shimmer-placeholder": "^2.0.8",
"react-native-svg": "12.1.1",
"react-native-uuid": "^2.0.1",
"react-native-web": "0.17.1",
"react-native-webview": "11.15.0",
"react-redux": "^7.2.6",
"semver-compare": "^1.0.0",
"sentry-expo": "^4.0.0",
"styled-components": "5.2.0",
"styled-system": "^5.1.5",
"validate.js": "^0.13.1"
},
"devDependencies": {
"@babel/core": "^7.12.9",
"@graphql-codegen/cli": "2.6.2",
"@graphql-codegen/typescript": "2.4.8",
"@graphql-codegen/typescript-operations": "2.3.5",
"@graphql-codegen/typescript-react-apollo": "3.2.11",
"@lingui/cli": "^3.13.2",
"@lingui/macro": "^3.13.2",
"@react-native-community/eslint-config": "^3.0.1",
"@types/jest": "^27.4.0",
"@types/react": "~17.0.21",
"@types/react-native": "~0.64.12",
"@types/react-native-animated-progress": "^1.0.0",
"@types/react-native-dotenv": "^0.2.0",
"@types/react-redux": "^7.1.23",
"@types/semver-compare": "^1.0.1",
"@types/styled-components": "^5.1.24",
"@types/styled-components-react-native": "5.1.0",
"@types/styled-system": "^5.1.15",
"@typescript-eslint/eslint-plugin": "^5.10.2",
"@typescript-eslint/parser": "^5.10.2",
"eslint": "^8.8.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^8.3.0",
"eslint-import-resolver-typescript": "^2.5.0",
"eslint-plugin-flowtype": "^8.0.3",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jest": "^26.1.0",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-hooks": "^4.3.0",
"graphql": "^16.3.0",
"install-peers": "^1.0.3",
"jest": "^27.5.0",
"prettier": "^2.5.1",
"react-native-config": "^1.4.5",
"react-native-svg-transformer": "^1.0.0",
"remote-redux-devtools": "^0.5.16",
"ts-jest": "^27.1.3",
"typescript": "~4.3.5"
},
"jest": {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
]
},
"resolutions": {
"react-devtools-core": "4.14.0",
"@types/react": "17.0.21",
"@types/react-dom": "17.0.01"
}
}
这是我的文件夹结构:
Here's MyAppPackage.kt (android\app\src\main\java\com\pana\MyAppPackage.kt
)
package com.pana // replace your-app-name with your app’s name
import android.view.View
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ReactShadowNode
import com.facebook.react.uimanager.ViewManager
class MyAppPackage : ReactPackage {
override fun createViewManagers(
reactContext: ReactApplicationContext
): MutableList<ViewManager<View, ReactShadowNode<*>>> = mutableListOf()
override fun createNativeModules(
reactContext: ReactApplicationContext
): MutableList<NativeModule> = listOf(CalendarModule(reactContext)).toMutableList()
}
以下是我重新整理的一些 SO 资源:
以下是我研究过的一些资源:
以下是我尝试过的一些错误和修复:
我已经尝试最小地增加我当前的项目(请注意,对于对讲包,我必须将 compileSdkVersion
和 targetSdkVersion
设置为 31,并且正在成功构建)。我关注了这个视频,官方的 React Native 文档,以及使用 Android Studio 将 Kotlin 添加到现有应用程序中(手动方法)。
a. (android/build.gradle) 已添加 (Inside buildscript.ext) kotlin_version = '1.4.10'
b. (android/build.gradle) 添加了(内部依赖项) 类路径 “org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version
” c. (android/app/build.gradle) 添加(在文件顶部) 应用插件:“kotlin-android”
尝试编译:
[stderr] Note: Recompile with -Xlint:deprecation for details.
> Task :app:compileDebugKotlin FAILED w: Runtime JAR files in the classpath should have the same version. These files were found in the classpath:
/home/expo/.gradle/caches/transforms-3/f47aaec93b5ce8275ab670559bc858c7/transformed/jetified-kotlin-stdlib-jdk8-1.5.31.jar (version 1.5)
/home/expo/.gradle/caches/transforms-3/e30ac7ea6364b484c3bc3c923afeabd2/transformed/jetified-kotlin-stdlib-jdk7-1.5.31.jar (version 1.5)
/home/expo/.gradle/caches/transforms-3/d9723caca13068e43e601371da49b5b2/transformed/jetified-kotlin-stdlib-1.6.10.jar (version 1.6)
/home/expo/.gradle/caches/transforms-3/c5966235c8aa66a583bf2afcd9edd1b7/transformed/jetified-kotlin-stdlib-common-1.6.10.jar (version 1.6) w: Some runtime JAR files in the classpath have an incompatible version. Consider removing them from the classpath [stderr] e: /home/expo/.gradle/caches/transforms-3/c5966235c8aa66a583bf2afcd9edd1b7/transformed/jetified-kotlin-stdlib-common-1.6.10.jar!/META-INF/kotlin-stdlib-common.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
看到这一点,我进行了一些研究,并建议将 Kotlin 版本推送到 1.6.10:
Task :expo-dev-launcher:compileDebugKotlin
[stderr] Compilation with Kotlin compile daemon was not successful
[stderr] java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
[stderr] java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
[stderr] java.io.InvalidClassException: org.jetbrains.kotlin.incremental.IncrementalModuleInfo; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 0
[stderr] at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:391)
[stderr] at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
[stderr] at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
[stderr] at java.base/java.security.AccessController.doPrivileged(Native Method)
[stderr] at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
[stderr] at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:562)
[stderr] at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:796)
[stderr] at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:677)
[stderr] at java.base/java.security.AccessController.doPrivileged(Native Method)
[stderr] at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:676)
[stderr] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
[stderr] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
[stderr] at java.base/java.lang.Thread.run(Thread.java:829)
[stderr] at java.rmi/sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:303)
[stderr] at java.rmi/sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:279)
[stderr] at java.rmi/sun.rmi.server.UnicastRef.invoke(UnicastRef.java:164)
这导致我更新以运行世博会升级和世博会医生
,看看是否有任何更新会
起作用。这打开了潘多拉的盒子。升级到 expo SDK 45 有其自身的问题(显然我有一些冲突的包,会引发以下错误):
[stderr] Note: /home/expo/workingdir/build/app/node_modules/@sentry/react-native/android/src/main/java/io/sentry/react/RNSentryModule.java uses or overrides a deprecated API.
[stderr] Note: Recompile with -Xlint:deprecation for details.
> Task :app:compileDebugJavaWithJavac FAILED
[stderr] /home/expo/workingdir/build/app/android/app/src/main/java/app/pana/MainApplication.java:6: error: package android.app does not exist
[stderr] import android.app.Application;
[stderr] ^
[stderr] /home/expo/workingdir/build/app/android/app/src/main/java/app/pana/MainApplication.java:7: error: package android.content does not exist
[stderr] import android.content.Context;
[stderr] ^
[stderr] /home/expo/workingdir/build/app/android/app/src/main/java/app/pana/MainApplication.java:8: error: package android.content.res does not exist
[stderr] import android.content.res.Configuration;
[stderr] ^
[stderr] /home/expo/workingdir/build/app/android/app/src/main/java/app/pana/MainApplication.java:10: error: package android.webkit does not exist
[stderr] import android.webkit.WebView;
还有其他版本在 expo-dev-client
中失败。我还知道 SDK 45 中的一个错误,即启用 Hermes 时会遇到问题。我们正在使用JSC。
只是为了防止这个问题变长,以下是我尝试过的其他事情:
一个。将 gradle-wrapper.properties
中的 distributionUrl
更改为更新的 gradle 版本。
b.更新和数学化org.jetbrains.kotlin:kotlin-gradle-plugin(在Android/build.gradle中),org.jetbrains.kotlin:kotlin-stdlib-jdk7
(将其更改为JDK8,什么都没有),org.jetbrains.kotlinx:kotlinx-coroutines-core,org.jetbrains.kotlinx:kotlinx-coroutines-android,
androidx.core:core-ktx以及相应的kotlin
版本。
c. 在调试实现语句中添加了这些实现
。
d. 研究了与 Kotlin 对应的 React Native 版本(不知道 Expo 的 SDK 44 版本 0.64 是否支持 Kotlin 1.6.10)。
e.已检查使用 Android Studio 是否存在语法错误。
f.冉冉干净。
g.还有其他事情...
有谁知道什么吗?世博会GitHub上似乎没有任何报道。
以下打包选项似乎有助于缓解某些问题
// android/app/build.gradle
android {
// This fixes a bug when
// https://github.com/facebook/react-native/issues/33120
packagingOptions {
jniLibs.useLegacyPackaging = true
}