Announcement

Collapse
No announcement yet.

androidx dependency issues: Didn't find class "android.support.v4.app.SupportActivity" on path

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    androidx dependency issues: Didn't find class "android.support.v4.app.SupportActivity" on path

    I built a minimal Unreal Engine 4.25.4 plugin with androidx dependencies, put it into a very simple project, and am trying to package the app for Android 29+ (and have configured the Unreal Editor to do so).The root of the issue I am trying to solve is duplicate classes in androidx and legacy dependencies.

    There are lots of examples for getting this working out there w/ Android Studio, and only a couple examples for Unreal Engine -> Android...and none of them worked for me. Below is the UPL file and a few other things I have tried to solve the androidx compat issue. Does anybody know how to solve this issue using Gradle?

    The app builds successfully with the UPL.xml file further down in this post, but when Unreal deploys the APK file to the phone it crashes immediately with this error:
    Code:
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: FATAL EXCEPTION: main
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: Process: com.example.myplugin, PID: 16597
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/app/BaseFragmentActivityApi16;
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at android.arch.lifecycle.LifecycleDispatcher.init(LifecycleDispatcher.java:55)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at android.arch.lifecycle.ProcessLifecycleOwnerInitializer.onCreate(ProcessLifecycleOwnerInitializer.java:35)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at android.content.ContentProvider.attachInfo(ContentProvider.java:2092)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at android.content.ContentProvider.attachInfo(ContentProvider.java:2066)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at android.app.ActivityThread.installProvider(ActivityThread.java:6983)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at android.app.ActivityThread.installContentProviders(ActivityThread.java:6528)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6445)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at android.app.ActivityThread.access$1300(ActivityThread.java:219)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1859)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:107)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at android.os.Looper.loop(Looper.java:214)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7356)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: android.support.v4.app.BaseFragmentActivityApi16
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at java.lang.VMClassLoader.findLoadedClass(Native Method)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:738)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at java.lang.ClassLoader.loadClass(ClassLoader.java:363)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: ... 15 more
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/app/BaseFragmentActivityApi14;
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: ... 15 more
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: android.support.v4.app.BaseFragmentActivityApi14
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at java.lang.VMClassLoader.findLoadedClass(Native Method)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at java.lang.ClassLoader.findLoadedClass(ClassLoader.java:738)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at java.lang.ClassLoader.loadClass(ClassLoader.java:363)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: ... 15 more
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/app/SupportActivity;
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: ... 15 more
    11-05 10:53:41.468 16597 16597 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v4.app.SupportActivity" on path: DexPathList[[zip file "/data/app/com.example.myplugin-qOQ_ANOu4wWHW-5-4RHeeA==/base.apk"],nativeLibraryDirectories=[/data/app/com.example.myplugin-qOQ_ANOu4wWHW-5-4RHeeA==/lib/arm, /data/app/com.example.myplugin-qOQ_ANOu4wWHW-5-4RHeeA==/base.apk!/lib/armeabi-v7a, /system/lib, /product/lib]]
    Using AndroidStudio to inspec the Dex files in the generated APK does not help because `SupportActivity` _is_ listed.


    UPL.xml:
    Code:
    <root xmlns:android="http://schemas.android.com/apk/res/android">
    <androidManifestUpdates>
    <addPermission android:name="android.permission.INTERNET" />
    <addPermission android:name="android.permission.READ_PHONE_STATE" />
    </androidManifestUpdates>
    <proguardAdditions>
    <!-- -keep class android.support.v4.app.SupportActivity.java -->
    </proguardAdditions>
    <buildGradleAdditions>
    <insert>
    repositories {
      mavenCentral()
    }
    
    dependencies {
      implementation 'androidx.core:core:1.3.2'
      implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
      implementation 'androidx.appcompat:appcompat:1.1.0'
    
      modules {
        module('com.android.support:support-compat') {
          replacedBy('androidx.core:core', 'androidx in use')
        }
      }
    }
    
    android {
      defaultConfig {
        multiDexEnabled true
      }
    }
    </insert>
    </buildGradleAdditions>
    <buildscriptGradleAdditions>
    <insert>
    </insert>
    </buildscriptGradleAdditions>
    <gradleProperties>
    <insert>
    <!--
    android.useAndroidX=true
    android.enableJetifier=true
    -->
    </insert>
    </gradleProperties>
    <baseBuildGradleAdditions>
    <insert>
    allprojects {
    def mappings = [
    'android.support.v4.app.NotificationCompat': 'androidx.core.app.NotificationCompat',
    'android.arch.lifecycle.Lifecycle': 'androidx.lifecycle.Lifecycle',
    'android.arch.lifecycle.OnLifecycleEvent': 'androidx.lifecycle.OnLifecycleEvent',
    'android.arch.lifecycle.ProcessLifecycleOwner': 'androidx.lifecycle.ProcessLifecycleOwner',
    'android.support.annotation.NonNull': 'androidx.annotation.NonNull',
    'android.support.annotation.NonNull': 'androidx.annotation.NonNull',
    'android.support.annotation.Nullable': 'androidx.annotation.Nullable',
    'android.support.v4.app.NotificationCompat': 'androidx.core.app.NotificationCompat',
    'android.support.v4.app.ActivityCompat': 'androidx.core.app.ActivityCompat',
    'android.support.v4.content.ContextCompat': 'androidx.core.content.ContextCompat',
    'android.support.v4.app.NotificationManagerCompat': 'androidx.core.app.NotificationManagerCompat',
    'android.support.v4.content.FileProvider': 'androidx.core.content.FileProvider',
    'android.support.v4.content.ContextCompat': 'androidx.core.content.ContextCompat'
    ]
    
    beforeEvaluate { project ->
      print(project.toString())
    
      task modifyAppGameActivityForRemovedPermissionsLibrary() {
        if (project.toString() == "project ':app'") {
          println 'modifyAppGameActivityForRemovedPermissionsLibrary: ' + "${System.getProperty('user.dir')}/app/src/main/java/com/epicgames/ue4/GameActivity.java"
    
          def file = "src/main/java/com/epicgames/ue4/GameActivity.java"
    
          ant.replace(file: file, token: 'com.google.vr.sdk.samples.permission.PermissionHelper', value: 'android.Manifest')
          ant.replace(file: file, token: 'PermissionHelper.checkPermission("android.permission.GET_ACCOUNTS")', value: 'checkCallingOrSelfPermission("android.permission.GET_ACCOUNTS") == PackageManager.PERMISSION_GRANTED')
          ant.replace(file: file, token: 'PermissionHelper.checkPermission("android.permission.WRITE_EXTERNAL_STORAGE")', value: '(checkCallingOrSelfPermission("android.permission.WRITE_EXTERNAL_STORAGE") == PackageManager.PERMISSION_GRANTED)')
        }
      }
    
      task modifyAppGradleProjectsForRemovedPermissionsLibrary() {
        if (project.toString() == "project ':app'") {
          println 'modifyAppGradleProjectsForRemovedPermissionsLibrary: ' + "${System.getProperty('user.dir')}/app/projects.gradle"
    
          ant.replace(file: "projects.gradle", token: "implementation project(':permission_library')", value: '')
        }
      }
    
      task removePermissionsLibraryFromGradleSettings() {
        println 'removePermissionsLibraryFromGradleSettings: ' + "${System.getProperty('user.dir')}/settings.gradle"
    
        ant.replace(file: "${System.getProperty('user.dir')}/settings.gradle", token: "include ':permission_library'", value: '')
      }
    
      project.rootProject.projectDir.traverse(type: groovy.io.FileType.FILES, nameFilter: ~/.*\.java$/) { f ->
        mappings.each { entry ->
          if (f.getText('UTF-8').contains(entry.key)) {
            println "mapping legacy ${entry.key} to ${entry.value} in file ${f}"
            ant.replace(file: f, token: entry.key, value: entry.value)
          }
        }
      }
     }
    }
    </insert>
    </baseBuildGradleAdditions>
    <gameActivityImportAdditions>
    <insert>
    //import androidx.etc;
    </insert>
    </gameActivityImportAdditions>
    <gameActivityClassAdditions>
    <insert>
    public void myCustomMethod() {
    
    }
    </insert>
    </gameActivityClassAdditions>
    </root>
    In UPL.xml I replace `com.android.support:support-compat` with `androidx.core:core` because _not_ doing that results in a build failure w/ duplicate classes. When I removed the module replacement, I got this error:

    Code:
    Execution failed for task ':app:checkDebugDuplicateClasses'.
    LogPlayLevel: > 1 exception was raised by workers:
    LogPlayLevel: java.lang.RuntimeException: Duplicate class android.support.v4.app.INotificationSideChannel found in modules core-1.3.2-runtime.jar (androidx.core:core:1.3.2) and support-compat-27.1.0-runtime.jar (com.android.support:support-compat:27.1.0)
    LogPlayLevel: Duplicate class android.support.v4.app.INotificationSideChannel$Stub found in modules core-1.3.2-runtime.jar (androidx.core:core:1.3.2) and support-compat-27.1.0-runtime.jar (com.android.support:support-compat:27.1.0)
    LogPlayLevel: Duplicate class android.support.v4.app.INotificationSideChannel$Stub$Proxy found in modules core-1.3.2-runtime.jar (androidx.core:core:1.3.2) and support-compat-27.1.0-runtime.jar (com.android.support:support-compat:27.1.0)
    LogPlayLevel: 27 actionable tasks: 6 executed, 21 up-to-date
    LogPlayLevel: Duplicate class android.support.v4.os.IResultReceiver found in modules core-1.3.2-runtime.jar (androidx.core:core:1.3.2) and support-compat-27.1.0-runtime.jar (com.android.support:support-compat:27.1.0)
    LogPlayLevel: Duplicate class android.support.v4.os.IResultReceiver$Stub found in modules core-1.3.2-runtime.jar (androidx.core:core:1.3.2) and support-compat-27.1.0-runtime.jar (com.android.support:support-compat:27.1.0)
    LogPlayLevel: Duplicate class android.support.v4.os.IResultReceiver$Stub$Proxy found in modules core-1.3.2-runtime.jar (androidx.core:core:1.3.2) and support-compat-27.1.0-runtime.jar (com.android.support:support-compat:27.1.0)
    LogPlayLevel: Duplicate class android.support.v4.os.ResultReceiver found in modules core-1.3.2-runtime.jar (androidx.core:core:1.3.2) and support-compat-27.1.0-runtime.jar (com.android.support:support-compat:27.1.0)
    LogPlayLevel: Duplicate class android.support.v4.os.ResultReceiver$1 found in modules core-1.3.2-runtime.jar (androidx.core:core:1.3.2) and support-compat-27.1.0-runtime.jar (com.android.support:support-compat:27.1.0)
    LogPlayLevel: Duplicate class android.support.v4.os.ResultReceiver$MyResultReceiver found in modules core-1.3.2-runtime.jar (androidx.core:core:1.3.2) and support-compat-27.1.0-runtime.jar (com.android.support:support-compat:27.1.0)
    LogPlayLevel: Duplicate class android.support.v4.os.ResultReceiver$MyRunnable found in modules core-1.3.2-runtime.jar (androidx.core:core:1.3.2) and support-compat-27.1.0-runtime.jar (com.android.support:support-compat:27.1.0)
    LogPlayLevel: Go to the documentation to learn how to <a href="d.android.com/r/tools/classpath-sync-errors">Fix dependency resolution errors</a>.
    I tried the solution here https://medium.com/nineva/how-to-for...x-f7060abd56ac initially, but could not get Jetpack to work out of the box with the `android.useAndroidX=true` and `android.enableJetifier=true` flags. When I enabled those flags, I got this error:

    Code:
    > Failed to apply plugin [id 'com.android.application']
    LogPlayLevel: > Cannot parse project property android.useAndroidX='true ' of type 'class java.lang.String' as boolean. Expected 'true' or 'false'.
    LogPlayLevel: * Try:
Working...
X