在我的React Native应用中,我禁用了Hermes,因为我需要使用Jitsi,而Jitsi不支持Hermes。
禁用Hermes后,我的应用开始为一些Android 10用户崩溃,我在Crashlytics上每天收到近100-200个崩溃报告。
这是我在app/build.gradle中的代码
apply plugin: "com.android.application"
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
import com.android.build.OutputFile
import org.apache.tools.ant.taskdefs.condition.Os
project.ext.react = [
enableHermes: false, // clean and rebuild if changing
entryFile: "index.js",
]
apply from: "../../node_modules/react-native/react.gradle"
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
def enableSeparateBuildPerCPUArchitecture = false
def enableProguardInReleaseBuilds = true
def jscFlavor = 'org.webkit:android-jsc:+'
def enableHermes = project.ext.react.get("enableHermes", false);
def reactNativeArchitectures() {
def value = project.getProperties().get("reactNativeArchitectures")
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
}
android {
ndkVersion rootProject.ext.ndkVersion
compileSdkVersion rootProject.ext.compileSdkVersion
defaultConfig {
applicationId "org.mentortogether.mentorship"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 902007
versionName "9.2.7"
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
if (isNewArchitectureEnabled()) {
externalNativeBuild {
cmake {
arguments "-DPROJECT_BUILD_DIR=$buildDir",
"-DREACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
"-DREACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build",
"-DNODE_MODULES_DIR=$rootDir/../node_modules",
"-DANDROID_STL=c++_shared"
}
}
if (!enableSeparateBuildPerCPUArchitecture) {
ndk {
abiFilters (*reactNativeArchitectures())
}
}
}
}
if (isNewArchitectureEnabled()) {
externalNativeBuild {
cmake {
path "$projectDir/src/main/jni/CMakeLists.txt"
}
}
def reactAndroidProjectDir = project(':ReactAndroid').projectDir
def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
into("$buildDir/react-ndk/exported")
}
def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
into("$buildDir/react-ndk/exported")
}
afterEvaluate {
preDebugBuild.dependsOn(packageReactNdkDebugLibs)
preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
configureCMakeRelWithDebInfo.dependsOn(preReleaseBuild)
configureCMakeDebug.dependsOn(preDebugBuild)
reactNativeArchitectures().each { architecture ->
tasks.findByName("configureCMakeDebug[${architecture}]")?.configure {
dependsOn("preDebugBuild")
}
tasks.findByName("configureCMakeRelWithDebInfo[${architecture}]")?.configure {
dependsOn("preReleaseBuild")
}
}
}
}
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK
include (*reactNativeArchitectures())
}
}
signingConfigs {
debug {
storeFile file('debug.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
release {
storeFile file('mentortogo-release-key.jks')
storePassword 'password'
keyAlias 'mentortogo'
keyPassword 'password'
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
signingConfig signingConfigs.release
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
flavorDimensions "mentortogo"
productFlavors {
staging {
dimension "mentortogo"
manifestPlaceholders = [bugsnagReleaseStage: "staging"]
}
prod {
dimension "mentortogo"
manifestPlaceholders = [bugsnagReleaseStage: "production"]
}
}
def versionArray = getNpmVersionArray()
applicationVariants.all { variant ->
variant.outputs.each { output ->
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
def abi = output.getFilter(OutputFile.ABI)
if (abi != null) { // null for the universal-debug, universal-release variants
output.versionCodeOverride =
versionCodes.get(abi) * 1048576 + versionArray[0]*10000 + versionArray[1]*100 + versionArray[2]
}
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation'com.facebook.soloader:soloader:0.11.0+'
implementation("com.facebook.react:react-native:+") {
exclude group: 'com.facebook', module: 'hermes'
}
implementation("com.facebook.react:react-native") {
version {
strictly "0.70.6"
}
}
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
exclude group:'com.facebook.fbjni'
}
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
exclude group:'com.squareup.okhttp3', module:'okhttp'
}
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
}
if (enableHermes) {
implementation("com.facebook.react:hermes-engine:+") { // From node_modules
exclude group:'com.facebook.fbjni'
}
} else {
implementation jscFlavor
}
}
if (isNewArchitectureEnabled()) {
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute(module("com.facebook.react:react-native"))
.using(project(":ReactAndroid"))
.because("On New Architecture we're building React Native from source")
substitute(module("com.facebook.react:hermes-engine"))
.using(project(":ReactAndroid:hermes-engine"))
.because("On New Architecture we're building Hermes from source")
}
}
}
task copyDownloadableDepsToLibs(type: Copy) {
from configurations.implementation
into 'libs'
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
def isNewArchitectureEnabled() {
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
}
这是我的build.gradle代码
import groovy.json.JsonSlurper
buildscript {
ext {
buildToolsVersion = "33.0.0"
minSdkVersion = 24
compileSdkVersion = 33
targetSdkVersion = 33
if (System.properties['os.arch'] == "aarch64") {
ndkVersion = "24.0.8215888"
} else {
ndkVersion = "21.4.7075529"
}
}
repositories {
google()
maven {
url 'https://maven.fabric.io/public'
}
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:6.6.1")
classpath("com.facebook.react:react-native-gradle-plugin")
classpath("de.undercouch:gradle-download-task:5.0.1")
classpath('com.google.gms:google-services:4.3.3')
classpath('io.fabric.tools:gradle:1.31.2')
classpath('com.bugsnag:bugsnag-android-gradle-plugin:5.+')
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.7.1'
}
}
allprojects {
repositories {
mavenCentral {
content {
excludeGroup "com.facebook.react"
}
}
google()
maven {
url ("$rootDir/../node_modules/react-native/android")
}
maven {
url "https://github.com/jitsi/jitsi-maven-repository/raw/master/releases"
}
maven {
url 'https://www.jitpack.io'
}
maven {
url "https://github.com/jitsi/jitsi-maven-repository/raw/master/releases"
}
configurations.all {
resolutionStrategy {
eachDependency { DependencyResolveDetails details ->
if (details.requested.group == 'com.facebook.react' && details.requested.name == 'react-native') {
def file = new File("$rootDir/../node_modules/react-native/package.json")
def version = new groovy.json.JsonSlurper().parseText(file.text).version
details.useVersion version
}
}
}
}
}
}
def getNpmVersionName() {
def inputFile = new File("../package.json")
def packageJson = new JsonSlurper().parseText(inputFile.text)
return packageJson["version"]
}
def getNpmVersionArray() {
def (major, minor, patch) = getNpmVersionName().minus(~/-.*/).tokenize('.')
return [Integer.parseInt(major), Integer.parseInt(minor), Integer.parseInt(patch)] as int[]
}
这是我的gradle.properties代码
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
# Version of flipper SDK to use with React Native
FLIPPER_VERSION=0.125.0
# Use this property to specify which architecture you want to build.
# You can also override it from the CLI using
# ./gradlew <task> -PreactNativeArchitectures=x86_64
reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
# Use this property to enable support to the new architecture.
# This will allow you to use TurboModules and the Fabric render in
# your application. You should enable this flag either if you want
# to write custom TurboModules/Fabric components OR use libraries that
# are providing them.
newArchEnabled=false
# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
hermesEnabled=false
android.disableAutomaticComponentCreation=true
我研究并尝试了React Native库仓库中提到的所有可能的解决方案来解决类似的问题,但到目前为止还没有成功。
这个问题影响了我应用程序的许多用户,影响非常大,所以需要尽快解决。
React Native版本
0.71.90
受影响的平台
运行时 - Android
npx react-native info
的输出
System:
OS: macOS 14.2.1
CPU: (8) arm64 Apple M2
Memory: 121.06 MB / 8.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 16.20.2 - ~/.nvm/versions/node/v16.20.2/bin/node
Yarn: 1.22.21 - /opt/homebrew/bin/yarn
npm: 8.19.4 - ~/.nvm/versions/node/v16.20.2/bin/npm
Watchman: 2024.04.08.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: Not Found
SDKs:
iOS SDK: Not Found
Android SDK: Not Found
IDEs:
Android Studio: 2022.3 AI-223.8836.35.2231.11090377
Xcode: /undefined - /usr/bin/xcodebuild
Languages:
Java: 11.0.22 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 18.1.0 => 18.1.0
react-native: 0.70.6 => 0.70.6
react-native-macos: Not Found
npmGlobalPackages:
*react-native*: Not Found
堆栈跟踪或日志
错误发生在以下设备上:
- Samsung Galaxy M20, Android 10
- Samsung Galaxy S20 5G, Android 10
- Samsung Galaxy M30, Android 10
- Vivo 1935, Android 10
- Samsung Galaxy A31, Android 10
- Redmi Note 7S, Android 10
- Jaina - Pegatron Gionee MAX, Android 10
- 以及更多其他设备
In my application, I disabled hermes as I am using Jitsi in my application and Jitsi was not working as expected with hermes, after disabling hermes Jitsi worked fine but after publishing the app I started to get this error on Crashlytics, and the issue is only occurring on some Android 10 devices.
Fatal Exception: java.lang.UnsatisfiedLinkError
dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/base.apk", zip file "/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.arm64_v8a.apk", zip file "/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.bn.apk", zip file "/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.en.apk", zip file "/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.gu.apk", zip file "/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.hi.apk", zip file "/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.mr.apk", zip file "/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.xxhdpi.apk"],nativeLibraryDirectories=[/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/lib/arm64, /data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/base.apk!/lib/arm64-v8a, /data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.arm64_v8a.apk!/lib/arm64-v8a, /data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.bn.apk!/lib/arm64-v8a, /data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.en.apk!/lib/arm64-v8a, /data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.gu.apk!/lib/arm64-v8a, /data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.hi.apk!/lib/arm64-v8a, /data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.mr.apk!/lib/arm64-v8a, /data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.xxhdpi.apk!/lib/arm64-v8a, /system/lib64, /vendor/lib64]]] couldn't find "libhermes.so"
Fatal Exception: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/base.apk", zip file "/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.arm64_v8a.apk", zip file "/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.bn.apk", zip file "/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.en.apk", zip file "/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.gu.apk", zip file "/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.hi.apk", zip file "/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.mr.apk", zip file "/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.xxhdpi.apk"],nativeLibraryDirectories=[/data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/lib/arm64, /data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/base.apk!/lib/arm64-v8a, /data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.arm64_v8a.apk!/lib/arm64-v8a, /data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.bn.apk!/lib/arm64-v8a, /data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.en.apk!/lib/arm64-v8a, /data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.gu.apk!/lib/arm64-v8a, /data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.hi.apk!/lib/arm64-v8a, /data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.mr.apk!/lib/arm64-v8a, /data/app/org.mentortogether.mentorship-AMBt-GyVwMiPAlRVJO5lMA==/split_config.xxhdpi.apk!/lib/arm64-v8a, /system/lib64, /vendor/lib64]]] couldn't find "libhermes.so"
at java.lang.Runtime.loadLibrary0(Runtime.java:1067)
at java.lang.Runtime.loadLibrary0(Runtime.java:1007)
at java.lang.System.loadLibrary(System.java:1667)
at com.facebook.soloader.nativeloader.SystemDelegate.loadLibrary(SystemDelegate.java)
at com.facebook.soloader.nativeloader.NativeLoader.loadLibrary(NativeLoader.java:52)
at com.facebook.soloader.nativeloader.NativeLoader.loadLibrary(NativeLoader.java:30)
at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:774)
at com.facebook.hermes.reactexecutor.HermesExecutor.loadLibrary(HermesExecutor.java:25)
at com.facebook.hermes.reactexecutor.HermesExecutor.<clinit>(HermesExecutor.java)
at com.facebook.hermes.reactexecutor.HermesExecutor.loadLibrary(HermesExecutor.java:23)
at com.facebook.react.ReactInstanceManagerBuilder.getDefaultJSExecutorFactory(ReactInstanceManagerBuilder.java:393)
at com.facebook.react.ReactInstanceManagerBuilder.build(ReactInstanceManagerBuilder.java:343)
at com.facebook.react.ReactNativeHost.createReactInstanceManager(ReactNativeHost.java:96)
at com.facebook.react.ReactNativeHost.getReactInstanceManager(ReactNativeHost.java:42)
at org.mentortogether.mentorship.MainApplication.onCreate(MainApplication.java:73)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1190)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6852)
at android.app.ActivityThread.access$1300(ActivityThread.java:268)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1982)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7807)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1047)
从错误跟踪来看,设备似乎在寻找hermes,但我已经禁用了它,所以这对我来说很奇怪。
我还在创建捆绑包之前清理了Gradle,并在内部测试环境中多次尝试过这个方法,结果也是一样的😢
6条答案
按热度按时间ru9i0ody1#
wmvff8tz2#
v64noz0r3#
看起来你已经将minSdkVersion设置为24@Abhishek-Khanduri,所以这可能与你有关。
huus2vyu4#
这是我在 app/build.gradle 中的代码
这是0.71项目中
app/build.gradle
文件应该看起来的样子:https://github.com/facebook/react-native/blob/0.71-stable/template/android/app/build.gradle
因此,您的应用程序肯定是配置错误的@Abhishek-Khanduri
xxe27gdn5#
我的最低SDK版本是21,但我多次遇到这个问题。@cortinico@brien-crean
iyfjxgzm6#
@sudhanshu-busy 我遵循了一种系统化的方法来排查并解决我们React Native应用在Android 10设备上的崩溃问题。以下是我采取的步骤:
设置示例应用程序:
配置传输:
build.gradle
和app/build.gradle
)从示例应用程序移动到我们的应用程序。增量配置添加:
确定问题代码片段:
注意到这个片段在示例应用程序的配置中不存在。
隔离问题:
这是我们怀疑导致问题的代码片段
您可以使用类似的方法追溯根本原因