Skip to main content

AppTrove SDK Android FAQ

This FAQ addresses common issues encountered when integrating the AppTrove SDK into Android applications, focusing on crashes, app size increases, and build configuration problems. Each issue includes detailed explanations and solutions, including ProGuard rules where applicable.


1. Why does my app crash with a ClassCastException in DaggerWorkerFactory when using the AppTrove SDK?

Issue: The app crashes with the following stack trace:

FATAL EXCEPTION: WM.task-4 (Ask Gemini)
Process: com.ultrajhakaas.android, PID: 28083
java.lang.ClassCastException: class com.trackier.sdk.BackgroundWorker cannot be cast to androidx.work.Worker
at java.lang.Class.asSubclass(Class.java:4229)
at com.mobiotics.vlive.android.worker.DaggerWorkerFactory.createWorker(DaggerWorkerFactory.kt:42)
at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:82)

Cause: This occurs due to a mismatch between the expected androidx.work.Worker class and the AppTrove SDK's BackgroundWorker class, often caused by incorrect class casting in the dependency injection setup or ProGuard rules stripping necessary classes.

Solution:

  • Ensure the AppTrove SDK is correctly integrated with WorkManager. Verify that the BackgroundWorker class extends androidx.work.Worker.
  • If the issue persists, it may be due to ProGuard optimizations removing necessary classes. Add the following ProGuard rules to your proguard-rules.pro file:
-keep class com.trackier.sdk.BackgroundWorker { *; }
-keep class androidx.work.Worker { *; }
-keep class kotlin.Metadata { *; }
-keep class kotlin.reflect.jvm.internal.** { *; }
-dontwarn kotlin.**

  • If the crash occurs in DaggerWorkerFactory.kt at line 42, check if the class name needs to be updated. Renaming or ensuring compatibility with the expected Worker class can resolve this issue.

2. Why do the install and event features of the AppTrove SDK stop working in release builds?

Issue: When switching from a debug to a release build with minifyEnabled and shrinkResources enabled, the AppTrove SDK's install and event tracking features stop functioning.

Cause: ProGuard or R8 optimizations in release builds may strip or obfuscate classes required by the AppTrove SDK, particularly those related to Kotlin reflection or metadata. This can interfere with the SDK's ability to process installs and events.

Solution:
Add the following ProGuard rules to your proguard-rules.pro file to preserve the necessary classes:

-keep class kotlin.Metadata { *; }
-keep class kotlin.reflect.jvm.internal.** { *; }
-keep class com.trackier.sdk.** { *; }
-dontwarn kotlin.**
-dontwarn com.trackier.sdk.**

Explanation:

  • -keep class kotlin.Metadata { *; }: Preserves Kotlin metadata required for reflection.
  • -keep class kotlin.reflect.jvm.internal.** { *; }: Ensures internal Kotlin reflection classes are not removed.
  • -keep class com.trackier.sdk.** { *; }: Preserves all AppTrove SDK classes to prevent obfuscation.
  • -dontwarn: Suppresses warnings for Kotlin and AppTrove SDK classes that may not be directly referenced but are required at runtime.

Additionally, ensure that minifyEnabled and shrinkResources are tested thoroughly in a staging environment before releasing to production.


3. Why does the app size increase by 200 KB to 1 MB after integrating the AppTrove SDK?

Issue: After integrating the AppTrove SDK, the APK size increases significantly, often by 200 KB to 1 MB.

Cause: The AppTrove SDK includes dependencies like the Kotlin Standard Library, Kotlin Reflection, and other libraries that contribute to the increased size. If your app already uses Kotlin, the SDK's inclusion of these dependencies may result in duplicated or unnecessarily large libraries.

Solution:
To minimize the size increase, optimize your app with the following steps:

  1. Review Dependencies: The AppTrove SDK includes the following dependencies, contributing to the size:
DependencySizeNotes
org.jetbrains.kotlin:kotlin-stdlib~1.5 MBKotlin Standard Library
org.jetbrains.kotlin:kotlin-reflect~2.5 MBKotlin Reflection Library
androidx.annotation:annotation~20 KBLightweight annotations
org.jetbrains.kotlinx:kotlinx-coroutines-core~300 KBCoroutines core library
androidx.work:work-runtime-ktx~500 KBWorkManager with Kotlin extensions
com.squareup.moshi:moshi-kotlin~200 KBMoshi JSON library
com.squareup.moshi:moshi-kotlin-codegen~50 KBMoshi codegen (compile-time only)
com.android.installreferrer:installreferrer~50 KBGoogle Play Install Referrer
com.miui.referrer:homereferrer~50 KBXiaomi Install Referrer
androidx.multidex:multidex~100 KBMultidex support (if >64K methods)
com.squareup.retrofit2:retrofit~100 KBRetrofit networking
com.squareup.retrofit2:converter-moshi~50 KBRetrofit Moshi converter
  1. Apply ProGuard Rules: Add the following rules to your proguard-rules.pro file to strip unused classes and reduce the APK size:
-dontwarn kotlin.reflect.jvm.**
-dontwarn kotlin.reflect.full.**
-dontwarn kotlin.reflect.jvm.KCallablesJvm
-dontwarn kotlin.reflect.full.KClasses
-dontwarn kotlin.reflect.jvm.internal.**

-keep class kotlin.Metadata { *; }
-keep class kotlin.reflect.jvm.internal.** { *; }
-keep class com.trackier.sdk.** { *; }
-dontwarn kotlin.**
-dontwarn com.trackier.sdk.**

-keep class kotlin.** {
public protected *;
}

  1. Enable R8 Optimizations: Ensure minifyEnabled is set to true in your build.gradle file to enable code shrinking and obfuscation. Combine this with shrinkResources true to remove unused resources.
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}

  1. Consider Multidex: If your app exceeds 64K methods, ensure multiDexEnabled true is set in your build.gradle file, and include the androidx.multidex:multidex dependency only if necessary.

  2. Analyze APK: Use Android Studio's APK Analyzer to identify which libraries contribute the most to the size and optimize accordingly.

Explanation:

  • The -dontwarn rules suppress warnings for unused Kotlin reflection classes, reducing the risk of ProGuard including unnecessary code.
  • The -keep rules ensure essential Kotlin and AppTrove SDK classes are preserved.
  • Enabling R8 and resource shrinking removes unused code and resources, mitigating the size increase caused by the SDK's dependencies.

4. How do I ensure compatibility with Kotlin-based dependencies in the AppTrove SDK?

Issue: The AppTrove SDK heavily relies on Kotlin, and conflicts may arise if your app uses a different Kotlin version or if ProGuard removes critical Kotlin classes.

Solution:

  1. Use Compatible Kotlin Versions: Ensure your app's Kotlin version is compatible with the AppTrove SDK. Check the SDK's documentation for the required Kotlin version and update your build.gradle accordingly:
buildscript {
ext.kotlin_version = '1.9.0' // Use the version specified by AppTrove SDK
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}

  1. Add ProGuard Rules for Kotlin: To prevent issues with Kotlin's reflection and metadata, include the following rules in proguard-rules.pro:
-keep class kotlin.Metadata { *; }
-keep class kotlin.reflect.jvm.internal.** { *; }
-dontwarn kotlin.**

  1. Test Thoroughly: Test your app in both debug and release builds to ensure that Kotlin-based features (e.g., coroutines, reflection) work correctly with the AppTrove SDK.

5. How do I troubleshoot other AppTrove SDK integration issues?

General Troubleshooting Steps:

  1. Check SDK Version: Ensure you are using the latest version of the AppTrove SDK. Update your build.gradle dependency:
dependencies {
implementation 'com.trackier:android-sdk:1.6.68'
}

  1. Verify ProGuard Rules: Double-check that all recommended ProGuard rules are included in proguard-rules.pro.
  2. Enable Logging: Enable debug logging in the AppTrove SDK to identify issues. Refer to the SDK's documentation for enabling verbose logs.
  3. Test in Staging: Test the SDK in a staging environment with minifyEnabled true to replicate release build conditions.
  4. Contact Support: If issues persist, contact AppTrove SDK support with the following details:
    • SDK version
    • App's Kotlin version
    • Stack trace (if applicable)
    • ProGuard rules used
    • Build configuration (minifyEnabled, shrinkResources)

Additional Resources

  • AppTrove SDK Documentation: Refer to the official AppTrove SDK documentation for detailed integration steps.
  • ProGuard Documentation: Learn more about ProGuard rules at proguard.sourceforge.io.
  • Android Developer Guide: Visit developer.android.com for guidance on optimizing APK size and configuring WorkManager.

For complete documentation, visit the Trackier Developer Portal.


6. Why does my app crash on Android 7 due to GMS (Google Mobile Services)?

Issue: The app crashes on Android 7 devices with the following error:

Caused by java.lang.NoClassDefFoundError: Failed resolution of: Ljava/time/Duration;
at com.google.android.gms.ads.identifier.zzd.<clinit>(zzd.java)
at com.google.android.gms.ads.identifier.zzd.zza(zzd.java)
at com.google.android.gms.ads.identifier.AdvertisingIdClient.getAdvertisingIdInfo(AdvertisingIdClient.java)
at java.lang.reflect.Method.invoke(Method.java)
at com.trackier.sdk.DeviceInfo$Companion.getGAID(DeviceInfo.java)
at com.trackier.sdk.TrackierSDKInstance.initGaid(SourceFile)
at com.trackier.sdk.TrackierSDKInstance.access$initGaid(SourceFile)
at com.trackier.sdk.TrackierSDKInstance$initialize$1.invokeSuspend(TrackierSDKInstance.java)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(BaseContinuationImpl.java)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.java:1)
at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.java:1)
at kotlinx.coroutines.scheduling.TaskImpl.run(TaskImpl.java:1)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.java:1)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.java:1)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.java:1)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.java:1)

Cause: This error occurs because Android 7 (API level 24) doesn't natively support the java.time.Duration class, which was introduced in Android 8 (API level 26). The Google Mobile Services (GMS) library tries to use this class, causing a NoClassDefFoundError.

Solution: Add the following dependency to your build.gradle file:

android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
// Add this dependency:
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
}
}

dependencies {
// Add this dependency:
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
}

Explanation: The coreLibraryDesugaring dependency provides backported versions of Java 8+ APIs (including java.time.Duration) for older Android versions, allowing the GMS library to work properly on Android 7 devices.