Описание проблемы
Мое приложение для Android прекрасно работает для большинства пользователей, но некоторые пользователи испытывают сбои сразу после запуска приложения. Приложение сбоятся еще до того, как даже показывает экран брызг, делая невозможным отладки посредством нормальной отчетности по сбою. /> попытки отладки < /strong> < /p>
1. Исследование фильтра ABI
Первоначально подозреваемые проблемы совместимости ABI, поэтому я настроил несколько архитектур в app/build.gradle:
Код: Выделить всё
android {
defaultConfig {
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
}
< /code>
Результат: проблема сохраняется после восстановления с помощью нескольких архитектур. < /p>
[b] 2. Minification Proguard/R8 [/b]
подозревал, что запутывание кода нарушает критические классы, поэтому я обновил правила прогира и отключил минимификацию для тестирования:
buildTypes {
release {
minifyEnabled false
// Also tried with proper ProGuard rules
}
}
< /code>
Результат: проблема по -прежнему происходит даже без минификации. < /p>
[b] 3. Испытательная лабораторная тестирование Firebase
Протестировала ту же модель Samsung Galaxy A12 в лаборатории Firebase Test с Android 12.
Результат: приложение запускает и отлично работает в тестовой лаборатории - не обнаружено сбоя. />Other devices[/b]: App works normally
[b]Test Lab:[/b] Same device model works fine
One related crash: Found one ABI-related crash in Crashlytics, but it was from a Pixel device, not Samsung
[b]Crashlytics crash log[/b]
Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{app.MainActivity}: java.lang.RuntimeException: java.util.concurrent.ExecutionException: com.getkeepsafe.relinker.MissingLibraryException: Could not find 'libflutter.so'. Looked for: [armeabi-v7a, armeabi], but only found: [].
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3897)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4076)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:91)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2473)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:219)
at android.app.ActivityThread.main(ActivityThread.java:8349)
at java.lang.reflect.Method.invoke(Method.java)
Код: Выделить всё
import com.android.build.api.dsl.Packaging
import java.io.FileInputStream
import java.util.Properties
plugins {
id("com.android.application")
// START: FlutterFire Configuration
id("com.google.gms.google-services")
id("com.google.firebase.crashlytics")
// END: FlutterFire Configuration
id("kotlin-android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}
// Read key.properties file
val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("android/key.properties")
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
android {
namespace = "my app namespace"
compileSdk = 36
ndkVersion = "27.0.12077973"
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
freeCompilerArgs += "-Xallow-jvm-ir-dependencies"
}
defaultConfig {
applicationId = "my app id"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = 23
targetSdk = 36
versionCode = 5
versionName = "1.0.2"
ndk {
abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a"))
}
}
signingConfigs {
create("release") {
keyAlias = keystoreProperties.getProperty("keyAlias")
keyPassword = keystoreProperties.getProperty("keyPassword")
storeFile = keystoreProperties.getProperty("storeFile")?.let { file(it) }
storePassword = keystoreProperties.getProperty("storePassword")
}
}
buildTypes {
debug {
ndk {
abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64"))
}
isMinifyEnabled = false
isShrinkResources = false
isDebuggable = true
isJniDebuggable = true
}
release {
ndk {
abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a"))
}
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android.txt"),
"proguard-rules.pro"
)
signingConfig = if (keystorePropertiesFile.exists()) {
signingConfigs.getByName("release")
} else {
signingConfigs.getByName("debug")
}
}
}
fun Packaging.() {
resources.pickFirsts.add("**/libc++_shared.so")
resources.pickFirsts.add("**/libjsc.so")
}
}
dependencies {
implementation("com.google.android.gms:play-services-ads:24.5.0")
}
flutter {
source = "../.."
}
Код: Выделить всё
allprojects {
repositories {
google()
mavenCentral()
}
}
val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get()
rootProject.layout.buildDirectory.value(newBuildDir)
subprojects {
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
project.layout.buildDirectory.value(newSubprojectBuildDir)
}
subprojects {
project.evaluationDependsOn(":app")
}
tasks.register("clean") {
delete(rootProject.layout.buildDirectory)
}
Код: Выделить всё
# Keep Google Play Core classes
-keep class com.google.android.play.core.** { *; }
-dontwarn com.google.android.play.core.**
# Keep Flutter Play Store classes
-keep class io.flutter.embedding.android.FlutterPlayStoreSplitApplication { *; }
-keep class io.flutter.embedding.engine.deferredcomponents.** { *; }
# Keep Google J2ObjC annotations
-keep class com.google.j2objc.annotations.** { *; }
-dontwarn com.google.j2objc.annotations.**
# Keep Guava classes
-keep class com.google.common.** { *; }
-dontwarn com.google.common.**
# Keep Google Play Core specific classes
-keep class com.google.android.play.core.splitcompat.** { *; }
-keep class com.google.android.play.core.splitinstall.** { *; }
-keep class com.google.android.play.core.tasks.** { *; }
# Firebase and Google services
-keep class com.google.firebase.** { *; }
-keep class com.google.android.gms.** { *; }
-dontwarn com.google.firebase.**
-dontwarn com.google.android.gms.**
# AdMob classes
-keep class com.google.android.gms.ads.** { *; }
-dontwarn com.google.android.gms.ads.**
# Flutter classes - Enhanced rules
-keep class io.flutter.** { *; }
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.view.** { *; }
-keep class io.flutter.embedding.** { *; }
-keep class io.flutter.plugins.** { *; }
-dontwarn io.flutter.embedding.**
# Flutter native libraries
-keep class io.flutter.embedding.engine.FlutterJNI { *; }
-keep class io.flutter.embedding.engine.loader.** { *; }
-keep class io.flutter.plugin.common.** { *; }
# Your app classes
-keep class site.tatbeqak.mg.mg_edu.** { *; }
# Keep native methods
-keepclasseswithmembernames class * {
native ;
}
# Keep JNI methods
-keepclasseswithmembernames class * {
public (android.content.Context, android.util.AttributeSet);
}
# Keep native library loading
-keep class java.lang.System {
public static void loadLibrary(java.lang.String);
public static void load(java.lang.String);
}
# Keep annotation classes
-keepattributes *Annotation*
-keepattributes Signature
-keepattributes EnclosingMethod
-keepattributes InnerClasses
-keepattributes RuntimeVisibleAnnotations
-keepattributes RuntimeInvisibleAnnotations
# Keep Serializable classes
-keepnames class * implements java.io.Serializable
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient ;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# Keep Parcelable classes
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
# Keep enum classes
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# Generic signatures
-keepattributes Signature
-keep class kotlin.** { *; }
-keep class kotlin.Metadata { *; }
-dontwarn kotlin.**
# R8 compatibility
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName ;
}
# Additional suppress warnings
-dontwarn javax.annotation.**
-dontwarn org.checkerframework.**
-dontwarn org.codehaus.mojo.animal_sniffer.**
-dontwarn java.lang.ClassValue
-dontwarn org.jetbrains.annotations.**
# Keep method names for reflection
-keepclassmembers class * {
@android.webkit.JavascriptInterface ;
}
# Platform calls Class.forName on types which do not exist on Android to determine platform
-dontnote junit.framework.**
-dontnote junit.runner.**
-dontwarn androidx.**
-dontwarn android.support.**
# OkHttp platform used only on JVM and when Conscrypt dependency is available
-dontwarn okhttp3.internal.platform.ConscryptPlatform
-dontwarn org.conscrypt.ConscryptHostnameVerifier
# Additional AdMob rules
-keep class com.google.android.gms.ads.internal.** { *; }
-dontwarn com.google.android.gms.ads.internal.**
# Keep all native methods
-keepclasseswithmembernames class * {
native ;
}
# Prevent obfuscation of classes with JNI methods
-keepclasseswithmembernames,includedescriptorclasses class * {
native ;
}
[b] androidmanifest [/b]
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
Есть какие -либо предложения по исправлению?
>
Подробнее здесь: https://stackoverflow.com/questions/797 ... ic-devices
Мобильная версия