Closed Peter-Warlock closed 4 years ago
@Peter-Warlock Thanks for reporting, this is odd you're seeing this crash since there is a class existent check just before attempting to use com.huawei.hms.api.HuaweiApiAvailability
. hasHMSAvailabilityLibrary
is called and returns early to prevent a call to isHMSCoreInstalledAndEnabled
in supportsHMS
.
My best guess is Proguard or R8 in your project is minifying extra code out of your app where these checks would have been.
Could you provide the following details so we can look into producing the issue?
app/build.gradle
proguard-rules.pro
file if you have one.
proguardFiles
in your app/build.gradle
as it might be a different name.Maybe it's Proguard or R8, but I don't see proguard rule here: https://documentation.onesignal.com/docs/android-sdk-setup
app/build.gradle
buildscript { repositories { mavenCentral() maven { url "https://plugins.gradle.org/m2/" } maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } jcenter() google() maven { url 'https://maven.google.com/' name 'Google' } } dependencies { classpath 'org.wisepersist:gwt-gradle-plugin:1.0.6' classpath 'com.android.tools.build:gradle:4.0.0' classpath 'com.mobidevelop.robovm:robovm-gradle-plugin:2.3.9' // firebase classpath 'com.google.gms:google-services:4.3.3' // Add the Firebase Crashlytics Gradle plugin. classpath 'com.google.firebase:firebase-crashlytics-gradle:2.2.0' // one signal //https://github.com/OneSignal/OneSignal-Gradle-Plugin/releases classpath 'gradle.plugin.com.onesignal:onesignal-gradle-plugin:0.12.8' } } allprojects { apply plugin: "eclipse" apply plugin: "idea" version = '1.0' ext { appName = "game7" gdxVersion = '1.9.10' roboVMVersion = '2.3.9' roboVMGradleVersion = '2.3.9' robopodsVersion = "2.2.3" altpodsVersion = "1.3.0-SNAPSHOT" // https://github.com/dkimitsa/robovm-robopods box2DLightsVersion = '1.4' ashleyVersion = '1.7.0' aiVersion = '1.8.0' } repositories { mavenCentral() jcenter() maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } maven { url "https://oss.sonatype.org/content/repositories/releases/" } maven { url "https://maven.google.com" } // new Google support Library source maven { url "https://artifactory.appodeal.com/appodeal" } // AppoDeal google() flatDir { dirs 'libs' } } } project(":desktop") { apply plugin: "java" dependencies { implementation project(":core") implementation "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion" //compile "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion" implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" implementation "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop" //compile "com.badlogicgames.gdx:gdx-controllers-lwjgl3:$gdxVersion" implementation "com.badlogicgames.gdx:gdx-controllers-desktop:$gdxVersion" implementation "com.badlogicgames.gdx:gdx-controllers-platform:$gdxVersion:natives-desktop" } } project(":android") { apply plugin: 'com.android.application' // Add the Firebase Crashlytics plugin. apply plugin: 'com.google.firebase.crashlytics' // one signal apply plugin: 'com.onesignal.androidsdk.onesignal-gradle-plugin' configurations { natives } dependencies { implementation project(":core") implementation "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion" natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi" natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a" natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-arm64-v8a" natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86" natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64" implementation "com.badlogicgames.gdx:gdx-freetype:$gdxVersion" natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi" natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi-v7a" natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-arm64-v8a" natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86" natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86_64" implementation "com.badlogicgames.gdx:gdx-controllers:$gdxVersion" implementation "com.badlogicgames.gdx:gdx-controllers-android:$gdxVersion" implementation 'androidx.multidex:multidex:2.0.1' implementation "com.googlecode.gwt-crypto:gwt-crypto:2.3.0" } } project(":core") { apply plugin: "java" dependencies { implementation "com.badlogicgames.gdx:gdx:$gdxVersion" implementation "com.badlogicgames.gdx:gdx-freetype:$gdxVersion" implementation "com.badlogicgames.gdx:gdx-controllers:$gdxVersion" } } tasks.eclipse.doLast { delete ".project" }
app/android/build.gradle
android { buildToolsVersion "29.0.3" compileSdkVersion 29 sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] assets { exclude '**/data/*' exclude '**/.Backup/*' exclude '**/.backup/*' exclude '**/.test/*' exclude '**/com.warlockstudio/*' } jniLibs.srcDirs = ['libs'] } } packagingOptions { exclude 'META-INF/robovm/ios/robovm.xml' } defaultConfig { minSdkVersion 16 targetSdkVersion 29 applicationId "com.warlockstudio.tank.combat.future.battles" multiDexEnabled true manifestPlaceholders = [ onesignal_app_id: 'xxxxxxxxx__here-my-onesignal_app_id__xxxxxxxxxxx', // Project number pulled from dashboard, local value is ignored. onesignal_google_project_number: 'REMOTE' ] setProperty("archivesBaseName", "$project.ext.appName-"+new Date().format('yyyyMMdd-HHmmss')) } buildTypes { release { shrinkResources true // This must be first minifyEnabled true // This must be after shrinkResources proguardFile 'D:/Android/asprojects/game7/android/proguard-project-new.cfg' } } aaptOptions { ignoreAssetsPattern '!*.Backup:!/data*:!data:!*.test:!/.test/*:!*com.warlockstudio:!/com.warlockstudio/*:' } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } // called every time gradle gets executed, takes the native dependencies of // the natives configuration, and extracts them to the proper libs/ folders // so they get packed with the APK. task copyAndroidNatives { doFirst { file("libs/armeabi/").mkdirs() file("libs/armeabi-v7a/").mkdirs() file("libs/arm64-v8a/").mkdirs() file("libs/x86_64/").mkdirs() file("libs/x86/").mkdirs() configurations.natives.files.each { jar -> def outputDir = null if (jar.name.endsWith("natives-arm64-v8a.jar")) outputDir = file("libs/arm64-v8a") if (jar.name.endsWith("natives-armeabi-v7a.jar")) outputDir = file("libs/armeabi-v7a") if(jar.name.endsWith("natives-armeabi.jar")) outputDir = file("libs/armeabi") if(jar.name.endsWith("natives-x86_64.jar")) outputDir = file("libs/x86_64") if(jar.name.endsWith("natives-x86.jar")) outputDir = file("libs/x86") if(outputDir != null) { copy { from zipTree(jar) into outputDir include "*.so" } } } } } tasks.whenTaskAdded { packageTask -> if (packageTask.name.contains("package")) { packageTask.dependsOn 'copyAndroidNatives' } } task run(type: Exec) { def path def localProperties = project.file("../local.properties") if (localProperties.exists()) { Properties properties = new Properties() localProperties.withInputStream { instr -> properties.load(instr) } def sdkDir = properties.getProperty('sdk.dir') if (sdkDir) { path = sdkDir } else { path = "$System.env.ANDROID_HOME" } } else { path = "$System.env.ANDROID_HOME" } def adb = path + "/platform-tools/adb" commandLine "$adb", 'shell', 'am', 'start', '-n', 'com.warlockstudio.game7/com.warlockstudio.game7.AndroidLauncher' } // sets up the Android Eclipse project, using the old Ant based build. eclipse { // need to specify Java source sets explicitly, SpringSource Gradle Eclipse plugin // ignores any nodes added in classpath.file.withXml sourceSets { main { java.srcDirs "src", 'gen' } } jdt { sourceCompatibility = 1.6 targetCompatibility = 1.6 } classpath { plusConfigurations += [project.configurations.compile] containers 'com.android.ide.eclipse.adt.ANDROID_FRAMEWORK', 'com.android.ide.eclipse.adt.LIBRARIES' } project { name = appName + "-android" natures 'com.android.ide.eclipse.adt.AndroidNature' buildCommands.clear(); buildCommand "com.android.ide.eclipse.adt.ResourceManagerBuilder" buildCommand "com.android.ide.eclipse.adt.PreCompilerBuilder" buildCommand "org.eclipse.jdt.core.javabuilder" buildCommand "com.android.ide.eclipse.adt.ApkBuilder" } } // sets up the Android Idea project, using the old Ant based build. idea { module { sourceDirs += file("src"); scopes = [COMPILE: [plus: [project.configurations.compile]]] iml { withXml { def node = it.asNode() def builder = NodeBuilder.newInstance(); builder.current = node; builder.component(name: "FacetManager") { facet(type: "android", name: "Android") { configuration { option(name: "UPDATE_PROPERTY_FILES", value: "true") } } } } } } } dependencies { implementation 'com.amplitude:android-sdk:2.25.2' implementation 'com.squareup.okhttp3:okhttp:3.12.2' // For minSDK lower than 21, change your OkHttp version to 3.12.2 in gradle like this // CONSENT SDK implementation 'com.google.android.ads.consent:consent-library:1.0.8' implementation 'com.android.installreferrer:installreferrer:1.1.2' // For Appodeal MyTarget implementation 'com.google.android.exoplayer:exoplayer-core:2.8.4' implementation 'com.google.android.exoplayer:exoplayer-hls:2.8.4' ///////////////////////////////////////////////////// // SUPPORT LIBRARY ///////////////////////////////////////////////////// // https://developers.google.com/android/guides/setup implementation 'androidx.appcompat:appcompat:1.1.0' //implementation 'com.google.firebase:firebase-core:17.4.1' implementation 'com.google.firebase:firebase-analytics:17.4.3' implementation 'com.google.firebase:firebase-ads:19.2.0' implementation 'com.google.firebase:firebase-crashlytics:17.1.0' implementation 'com.google.android.gms:play-services-games:19.0.0' implementation 'com.google.android.gms:play-services-analytics:17.0.0' implementation 'com.facebook.android:facebook-android-sdk:5.8.0' // one signal https://github.com/OneSignal/OneSignal-Android-SDK/releases implementation 'com.onesignal:OneSignal:3.15.1' implementation ('com.appodeal.ads:sdk:2.6.4.+') { exclude group: 'com.appodeal.ads.sdk.networks', module: 'amazon_ads' exclude group: 'com.appodeal.ads.sdk.networks', module: 'appodeal' exclude group: 'com.appodeal.ads.sdk.networks', module: 'facebook' exclude group: 'com.appodeal.ads.sdk.networks', module: 'nast' exclude group: 'com.appodeal.ads.sdk.networks', module: 'tapjoy' exclude group: 'com.appodeal.ads.sdk.networks', module: 'yandex' exclude group: 'com.appodeal.ads.sdk.networks', module: 'vungle' } implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs') } apply plugin: 'com.google.gms.google-services'
proguard-project-new.cfg
# To enable ProGuard in your project, edit project.properties # to define the proguard.config property as described in that file. # # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in ${sdk.dir}/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the ProGuard # include property in project.properties. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: -verbose -dontwarn android.support.** -dontwarn com.badlogic.gdx.backends.android.AndroidFragmentApplication -dontwarn com.badlogic.gdx.utils.GdxBuild -dontwarn com.badlogic.gdx.physics.box2d.utils.Box2DBuild -dontwarn com.badlogic.gdx.jnigen.BuildTarget* -dontwarn com.badlogic.gdx.graphics.g2d.freetype* ############################################ -optimizationpasses 3 -ignorewarnings -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontpreverify -verbose -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* -printconfiguration ############################################ ############################################ #CrashlyticsCore ############################################ -keep class com.crashlytics.** { *; } -keep class com.google.android.gms.measurement.** { *; } -keep class com.google.android.gms.measurement.AppMeasurement { *; } -keep class com.google.android.gms.measurement.AppMeasurement$OnEventListener { *; } -dontwarn com.google.android.gms.measurement.** ############################################ # libGDX ############################################ -keepclassmembers class com.badlogic.gdx.backends.android.AndroidInput* { <init>(com.badlogic.gdx.Application, android.content.Context, java.lang.Object, com.badlogic.gdx.backends.android.AndroidApplicationConfiguration); } -keepclassmembers class com.badlogic.gdx.physics.box2d.World { boolean contactFilter(long, long); void beginContact(long); void endContact(long); void preSolve(long, long); void postSolve(long, long); boolean reportFixture(long); float reportRayFixture(long, float, float, float, float, float); } -keep class com.badlogic.gdx.backends.** { *; } -keep class com.badlogic.gdx.math.** { *; } -keep class com.badlogic.gdx.Gdx.** { *; } -keep class com.badlogic.gdx.assets.** { *; } -keep class com.badlogic.gdx.audio.** { *; } -keep class com.badlogic.gdx.graphics.** { *; } -keep class com.badlogic.gdx.utils.** { *; } -keep class com.badlogic.gdx.Net.** { *; } -keep class com.badlogic.gdx.files.** { *; } -keep class com.badlogic.gdx.InputMultiplexer.** { *; } -keep class com.badlogic.gdx.controllers.** { *; } -keep class * implements com.badlogic.gdx.utils.Json* -keep class com.badlogic.gdx.jnigen.NativeCodeGenerator -keep class com.badlogic.gdx.jnigen.AntScriptGenerator -keep class com.badlogic.gdx.jnigen.BuildConfig -keep class com.badlogic.gdx.jnigen.AntScriptGenerator -keep class com.google.android.chimera.** { *; } -keep class com.google.android.apps.gmm.** { *; } -keep class android.app.job.** { *; } -keep class android.app.job.JobScheduler.** { *; } -keep class android.util.Rational.** { *; } -keep class javax.net.ssl.** { *; } -keep class com.google.android.gms.** { *; } -keep class android.graphics.drawable.RippleDrawable.** { *; } -keep class android.media.** { *; } -keep class android.content.ContextWrapper.** { *; } -keep class android.content.pm.** { *; } -keep class android.app.NotificationManager.** { *; } # FOR VUNGLE #-keep class android.support.v13.** { *; } -keep class com.vungle.publisher.FullScreenAdActivity { *; } # Preserve the special static methods that are required in all enumeration classes. -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } #-keep class com.badlogic.gdx.** { # *; #} ############################################# # GOOGLE BILLING ############################################# -keep class com.android.vending.billing.** ############################################# # Amplitude SDK ############################################# -keep class com.google.android.gms.ads.** { *; } -dontwarn okio.** ############################################# # APPODEAL ############################################# -dontwarn com.appodeal.ads.** -dontwarn com.chartboost.** -dontwarn com.mopub.** -dontwarn com.facebook.** -dontwarn com.jirbo.adcolony.** -dontwarn com.vungle.** -dontwarn com.startapp.** -dontwarn com.yandex.** -dontwarn com.inmobi.** -dontwarn com.appodeal.ads.utils.** -dontwarn com.google.android.gms.internal.** -dontwarn com.cmcm.adsdk.** # Cheetah -keep class com.cmcm.adsdk.** { *;}
No. I don't see this bug at testing. But Firebase notify me about "trending issue" for a new build a day after I released a new version with 3.15.1. 43% of devices with that issue is HUAWEI, 21%=vivo, 19%=OPPO. As I said before, I don't have Huawai, I don't use any Huawei SDK or API. Also, Huawei is not most popular device for this game. Most popular as usual Samsung + Xiaomi, but as I see there is no crash with that devices. 28% of devices with Android 6, 70% of devices - device state = background.
Here the link into Google Play: https://play.google.com/store/apps/details?id=com.warlockstudio.tank.combat.future.battles
Do you have any news? Almost a hundred crashes every day! Is there any way to get rid of this bug? ASAP!
@Peter-Warlock Thanks for the details, I was not able to reproduce the issue by using your proguard-project-new.cfg
and some of the basic settings from your build.gradle
files. However I did take a look at your APK and found that the class exists checks for HMS were completely non-existent which will cause this issue. I believe the only thing that should be minifying code is Proguard and R8 as part of the normal Android Studio / Gradle build process, unless you have some else you run your app through?
Libraries can also their own consumer Proguard configuration changes, normally this is a safelist but one of them could be making other changes.
Please add the following to your proguard-project-new.cfg
.
-printconfiguration proguard_printconfiguration.txt
This will generate a full Proguard file including settings from all libraries as well so we can attempt to reproduce the issue. The proguard_printconfiguration.txt
should be located under you app
folder, however if you have issues finding it then you can change this to a full path instead.
As a quick fix you could add the following which will prevent Proguard and R8 from minifying the code.
-keep class com.onesignal.** {*;}
The only downside being an APK size increase of a few 100 KB
I added
-keep class com.onesignal.** {*;}
in pro-guard. Build new build of the game. The size increased. Ok, I upload it into Google Play. Wait, and got the same
Trending issues. Issues rapidly gaining momentum OSUtils.java line 168com.onesignal.OSUtils.hasHMSAvailabilityLibrary
Right now this issue has 574 crashes affecting 175 users.
Fatal Exception: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/huawei/hms/api/HuaweiApiAvailability; at com.onesignal.OSUtils.hasHMSAvailabilityLibrary(OSUtils.java:168) at com.onesignal.OSUtils.supportsHMS(OSUtils.java:324) at com.onesignal.OSUtils.getDeviceType(OSUtils.java:360) at com.onesignal.OSUtils.isAndroidDeviceType(OSUtils.java:378) at com.onesignal.LocationController.isGooglePlayServicesAvailable(LocationController.java:286) at com.onesignal.LocationController.onFocusChange(LocationController.java:274) at com.onesignal.OneSignal.onAppLostFocus(OneSignal.java:1251) at com.onesignal.ActivityLifecycleHandler$AppFocusRunnable.run(ActivityLifecycleHandler.java:263) at android.os.Handler.handleCallback(Handler.java:888) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:213) at android.os.HandlerThread.run(HandlerThread.java:67)
Caused by java.lang.ClassNotFoundException: com.huawei.hms.api.HuaweiApiAvailability at com.onesignal.OSUtils.hasHMSAvailabilityLibrary(OSUtils.java:168) at com.onesignal.OSUtils.supportsHMS(OSUtils.java:324) at com.onesignal.OSUtils.getDeviceType(OSUtils.java:360) at com.onesignal.OSUtils.isAndroidDeviceType(OSUtils.java:378) at com.onesignal.LocationController.isGooglePlayServicesAvailable(LocationController.java:286) at com.onesignal.LocationController.onFocusChange(LocationController.java:274) at com.onesignal.OneSignal.onAppLostFocus(OneSignal.java:1251) at com.onesignal.ActivityLifecycleHandler$AppFocusRunnable.run(ActivityLifecycleHandler.java:263) at android.os.Handler.handleCallback(Handler.java:888) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:213) at android.os.HandlerThread.run(HandlerThread.java:67)
It just a stupid! Why you call this freaking huawai code if I don't use any freaking huawei api? Why you call com.huawei.xxx without checking is it available or not? Why you don't wrap it by try...catch to prevent with stupid crashing? Tell me ASAP, how fast you can fix this stupid bug and give me a real working version without that lamer's bugs.
Please help, I am running into the same issue
Caused by java.lang.ClassNotFoundException
Didn't find class "com.huawei.hms.api.HuaweiApiAvailability" on path: DexPathList[[zip file "/data/app/live.free.tv_tw-1/base.apk", zip file "/data/app/live.free.tv_tw-1/split_config.armeabi_v7a.apk", zip file "/data/app/live.free.tv_tw-1/split_config.hdpi.apk", zip file "/data/app/live.free.tv_tw-1/split_config.zh.apk"],nativeLibraryDirectories=[/data/app/live.free.tv_tw-1/lib/arm, /vendor/lib, /system/lib]]
@Peter-Warlock
Thanks for the latest stacktrace.
We already have a try-catch for NoClassDefFoundError
exactly where your crash is being reported.
https://github.com/OneSignal/OneSignal-Android-SDK/blob/3.15.1/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSUtils.java#L166-L171
It seems -keep class com.onesignal.** {*;}
resulted not obfuscating / minifying the OneSignal classes. However something in your build process is still removing catches that it should not. Specific the catches for NoClassDefFoundError
in this case, possibly others.
There have been some reports of Proguard bugs with removing try-catches. However they seem to have been fixed log ago
I also tried to search the R8 bug tracker but did not find any things specific enough to your case. https://issuetracker.google.com/issues?q=componentid:326788%20NoClassDefFoundError%20 However there could still be a bug with R8 under very specific conditions.
We will need to be able to reproduce the issue on our end to help find the root cause.
printconfiguration
noted my https://github.com/OneSignal/OneSignal-Android-SDK/issues/1085#issuecomment-655674615 above.enableR8
in your gradle.properties
or anywhere in your project.Our test APK built with your provided proguard-project-new.cfg
.
.method private static hasHMSAvailabilityLibrary()Z
.registers 2
.line 168
:try_start_0
const-class v0, Lcom/huawei/hms/api/HuaweiApiAvailability;
:try_end_2
.catch Ljava/lang/NoClassDefFoundError; {:try_start_0 .. :try_end_2} :catch_4
const/4 v0, 0x1
return v0
.line 169
:catch_4
move-exception v0
.line 170
.local v0, "e":Ljava/lang/NoClassDefFoundError;
const/4 v1, 0x0
return v1
.end method
From your APK on the Google Play Store
.method private static hasHMSAvailabilityLibrary()Z
.registers 1
.line 168
const-class v0, Lcom/huawei/hms/api/HuaweiApiAvailability;
const/4 v0, 0x1
return v0
.end method
The smali from your APK shows that the catch for NoClassDefFoundError
is not in your dex's bytecode in your released APK. Why this is the case is unknown until we have a build process reproducing the outputted results as an APK.
The above was discovered with the jadx tool: https://github.com/skylot/jadx
Open your APK with jadx and look for hasHMSPushKitLibrary
. Then select smali on the bottom tab (jadex does NOT correctly show you the catch with it's java code option . If you see a catch for NoClassDefFoundError
under this method your build process is setup correctly.
After you have jadx setup you can perform some trial and error if you wish to attempt to fix the error from your end. If you found a solution let us know as I can help others.
@b99202021 Your message is different, this is an expected warning when the app is started. It won't have any effect on the runtime of your app.
@jkasten2
I looked in your source code and now I see the problem. The way you checked for class exist or not is wrong. Minifier will remove try....catch... because you can't build this code if you don't have that class -> if you have it - you don't need try...catch.
Here is correct and worked code:
public boolean isClass(String className) {
try {
Class.forName(className);
return true;
} catch (final ClassNotFoundException e) {
return false;
}
}
Class.forName able to generate ClassNotFoundException exception, Minifier know about it, so no one will remove try...catch in this case.
Usage in your case is like this:
private static boolean hasHMSAvailabilityLibrary() {
return isClass("com.huawei.hms.api.HuaweiApiAvailability");
}
I tested it. I builded APK with a both ways. I don't have any huawai api, so I changed it to Applovin classes just for test. Here decompiled result as code.
..and as smali
After releasing the game with that bug, my daily new users dropped by x10. So, few days ago, I tired to wait fast fix from you and just rolled back to v3.13.1 of OneSignal.
I hope you will change the way as you cheked for class exist to way as I gave you in this message and it will solve the problem.
@Peter-Warlock Thanks for the suggestion, however we have had issues with string based runtime detection if a class exists with proguard as well. Instead of the try-catch being removed the SDK won't think the class is there when it is as Proguard renames the class.
Please provide the details above so we reproduce the try-catch removal, we should be able to find a solution from there.
The crash you are seeing only happens if the device has disabled the "Google Play services" app on the device. If they downloaded your app from the Google Play store this won't be a problem as they would have needed it to download your app. https://github.com/OneSignal/OneSignal-Android-SDK/blob/3.15.1/OneSignalSDK/onesignal/src/main/java/com/onesignal/OSUtils.java#L356-L357 However if your app is on other stores then this would be a larger problem. In that case using OneSignal at version 3.14.X would be recommend until we can solve this issue.
@jkasten2 How proguard can rename system class com.huawei.hms.api.HuaweiApiAvailability? Proguard can obfuscate some inner classes, that was not be marked as -keep class xxxx, but how it can obfuscate a system classes? Or use -keep class com.huawei.hms.api.* {;} at the build time of your SDK if it's not a system class.
I don't upload the game in store other than Google Play. As I said before, I don't use any huawai api and don't upload it to AppGalery Store.
OneSignal v3.13.1 so far seems good.
Info that you asked:
here is printconfiguration for the latest build with OneSignal 3.15.1 proguard_printconfiguration.txt
I tried R8 as it was released as pre-release, but got some strange bugs in some strange place on some old devices with Mediatec chip. I was contacted Google, they tried to fix it, but at least in the next version it was not fixed. So, I disabled R8 and continue to use ProGuard by using: android.enableR8 = false in my gradle.properties. I used the latest release of Android Studio 4.0.
I don't use any other obfuscation tools.
Hope it will help.
@Peter-Warlock Thanks for the full proguard config, I was able to reproduce the issue!
It seems since there isn't a method call or other evaluations in the try or catch it seem Proguard thought it was safe to remove. Simply changing com.huawei.hms.api.HuaweiApiAvailability.class.getName();
from a null
check resulted in keeping the try-catch. I have fixed this in PR #1098 with more details.
The issue only affects Proguard it seems, not R8. Also only if specific Proguard settings are used. One being proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rule.pro'
. However if the less aggressive 'proguard-android.txt'
is used with Proguard there also was not an issue.
@jkasten2 Glad to hear it!!! So, it will be fixed in next release?
@Peter-Warlock Yes, correct, thanks for providing all the requested details! Wouldn't have been able to reproduce and hunt down the issue without them.
This problem has resurfaced with your version: 4.6.3. for us [Audiomack]. The stacks looks similar but still I am uploading the latest stack-trace from Firebase.
Stack-trace
Fatal Exception: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/huawei/hms/api/HuaweiApiAvailability; at com.onesignal.OSUtils.isHMSCoreInstalledAndEnabled(OSUtils.java:289) at com.onesignal.OSUtils.supportsHMS(OSUtils.java:317) at com.onesignal.OSUtils.getDeviceType(OSUtils.java:349) at com.onesignal.OSUtils.initializationChecker(OSUtils.java:112) at com.onesignal.OneSignal.init(OneSignal.java:796) at com.onesignal.OneSignal.setAppId(OneSignal.java:692) at com.onesignal.OneSignal.reassignDelayedInitParams(OneSignal.java:1136) at com.onesignal.OneSignal.onRemoteParamSet(OneSignal.java:844) at com.onesignal.OneSignal$6.complete(OneSignal.java:1077) at com.onesignal.OneSignalRemoteParams.processJson(OneSignalRemoteParams.java:206) at com.onesignal.OneSignalRemoteParams.access$100(OneSignalRemoteParams.java:12) at com.onesignal.OneSignalRemoteParams$1.onSuccess(OneSignalRemoteParams.java:151) at com.onesignal.OneSignalRestClient$5.run(OneSignalRestClient.java:283) at java.lang.Thread.run(Thread.java:818)
Caused by java.lang.ClassNotFoundException: Didn't find class "com.huawei.hms.api.HuaweiApiAvailability" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/data/app/com.audiomack-1/base.apk"],nativeLibraryDirectories=[/data/app/com.audiomack-1/lib/arm64, /data/app/com.audiomack-1/base.apk!/lib/arm64-v8a, /vendor/lib64, /system/lib64]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) at java.lang.ClassLoader.loadClass(ClassLoader.java:511) at java.lang.ClassLoader.loadClass(ClassLoader.java:469) at com.onesignal.OSUtils.isHMSCoreInstalledAndEnabled(OSUtils.java:289) at com.onesignal.OSUtils.supportsHMS(OSUtils.java:317) at com.onesignal.OSUtils.getDeviceType(OSUtils.java:349) at com.onesignal.OSUtils.initializationChecker(OSUtils.java:112) at com.onesignal.OneSignal.init(OneSignal.java:796) at com.onesignal.OneSignal.setAppId(OneSignal.java:692) at com.onesignal.OneSignal.reassignDelayedInitParams(OneSignal.java:1136) at com.onesignal.OneSignal.onRemoteParamSet(OneSignal.java:844) at com.onesignal.OneSignal$6.complete(OneSignal.java:1077) at com.onesignal.OneSignalRemoteParams.processJson(OneSignalRemoteParams.java:206) at com.onesignal.OneSignalRemoteParams.access$100(OneSignalRemoteParams.java:12) at com.onesignal.OneSignalRemoteParams$1.onSuccess(OneSignalRemoteParams.java:151) at com.onesignal.OneSignalRestClient$5.run(OneSignalRestClient.java:283) at java.lang.Thread.run(Thread.java:818)
Description: Just updated to version 3.15.1 from 3.14.1 to fix issue OneSignalCacheCleaner.java and got a new trending issue.
Trending stability issues: OSUtils.java line 300 com.onesignal.OSUtils.isHMSCoreInstalledAndEnabled
I don't need and don't use any Huawei SDK and API. Is it possible to get some version of your SDK that will not cause a trending issue? There is exist some one version without a fatal bugs?