Search Unity

androidx vs. android libraries

Discussion in 'Android' started by Tom-Atom, Jul 15, 2019.

  1. Tom-Atom

    Tom-Atom

    Joined:
    Jun 29, 2014
    Posts:
    153
    Hi,

    some libraries I use have dependency on "com.android.support:support-v4"

    When I bild and run my game, I get runtime error:

    java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/content/ContextCompat;

    I found, that Play Services Resolver is pretty agressive in replacing old android libraries with androidx ones. In fact, it looks it is not possible to stop it from actively switching on Jetifier and if you try it (answering no), then rosolving fails.

    com.android.support:support-v4 is one of the old libraries, that are replaced.

    It took me whole day to find, that it is not enough to have androidx libraries in <Project>\Temp\gradleOut\build.gradle file. You should also have these two additional lines in gradle.properties:

    android.useAndroidX = true
    android.enableJetifier = true

    Unfortunately, gradle.properties is generated by Unity and is overwritten every time. Then I found this answer from person, that deserves gold medal for it. Using his script...:

    Code (CSharp):
    1. using System.IO;
    2. using UnityEditor.Android;
    3. using UnityEngine;
    4.  
    5. public class AndroidPostBuildProcessor : IPostGenerateGradleAndroidProject {
    6.     public int callbackOrder {
    7.         get {
    8.             return 999;
    9.         }
    10.     }
    11.  
    12.     void IPostGenerateGradleAndroidProject.OnPostGenerateGradleAndroidProject(string path) {
    13.         Debug.Log("Bulid path : " + path);
    14.         string gradlePropertiesFile = path + "/gradle.properties";
    15.         if (File.Exists(gradlePropertiesFile)) {
    16.             File.Delete(gradlePropertiesFile);
    17.         }
    18.         StreamWriter writer = File.CreateText(gradlePropertiesFile);
    19.         writer.WriteLine("org.gradle.jvmargs=-Xmx4096M");
    20.         writer.WriteLine("android.useAndroidX=true");
    21.         writer.WriteLine("android.enableJetifier=true");
    22.         writer.Flush();
    23.         writer.Close();
    24.  
    25.     }
    26. }
    27.  
    ... adds required lines into gradle.properties and game stops crashing.

    So, working with androidx libraries seems to be only half-way done. It is pushed by Play Services Resolver, but missing in gradle.properties.
     
  2. AmdRin

    AmdRin

    Joined:
    Oct 20, 2015
    Posts:
    14
    Hello, I tried to use this script in my project. But the moment I start build the project it failed and show some error.


    Code (CSharp):
    1. Assets\AndroidPostBuildProcessor.cs(2,19): error CS0234: The type or namespace name 'Android' does not exist in the namespace 'UnityEditor' (are you missing an assembly reference?)
    2.  
    3. Assets\AndroidPostBuildProcessor.cs(5,42): error CS0246: The type or namespace name 'IPostGenerateGradleAndroidProject' could not be found (are you missing a using directive or an assembly reference?)
    4.  
    5. Assets\AndroidPostBuildProcessor.cs(15,10): error CS0246: The type or namespace name 'IPostGenerateGradleAndroidProject' could not be found (are you missing a using directive or an assembly reference?)
    6.  
    7.  
     
  3. Tom-Atom

    Tom-Atom

    Joined:
    Jun 29, 2014
    Posts:
    153
    Did you place it into "Editor" folder?
     
    KalAnthony likes this.
  4. AmdRin

    AmdRin

    Joined:
    Oct 20, 2015
    Posts:
    14
    Not yet. I will move it first, thank you.
     
  5. CliveLewis

    CliveLewis

    Joined:
    Feb 20, 2017
    Posts:
    5
    To everyone who will get confused: You need unity 2018.2 to have access to the IPostGenerateGradleAndroidProject interface. I tried to use it in Unity 2017.4 and didn't understand why it doesn't work ;)
     
    Last edited: Aug 6, 2019
  6. yigitekimdemir

    yigitekimdemir

    Joined:
    Jan 10, 2019
    Posts:
    3
    I am a newbie Unity user and i was getting mad with gradle failure because of play resolver. I thank you sincerely for your solution to the problem as I could not find or invent it myself. Works fine in Unity 2018.4.
     
  7. dohaiha930

    dohaiha930

    Joined:
    Mar 27, 2018
    Posts:
    55
    @Tom-Atom : Thank bro! It work like a charm!
     
  8. IvyKun

    IvyKun

    Joined:
    Sep 28, 2013
    Posts:
    132
    I encountered this problem today and was able to know what was happening thanks to it! So Thanks!

    Also, with new versions of Unity play services resolver will add those lines for you.

    First you need to enable "Custom Gradle Template" in player settings.
    Second, enable "Path mainTemplate.gradle" in play services resolver android settings.

    Then resolve or force resolve again, those lines will be added to the mainTemplate.gradle file and your build will not crash.
     
    alex_roboto likes this.
  9. dohaiha930

    dohaiha930

    Joined:
    Mar 27, 2018
    Posts:
    55
    You can disable whole Resolver, and use pure Gradle things like what i do it for now, never encounter any conflict from this.
     
  10. tummygames

    tummygames

    Joined:
    Dec 12, 2017
    Posts:
    10
    Hey guys,
    So it was like 24h for me to figure this damm thing so i wan't to share what I did since I use Mac I started from Updating Unity's gradle from 5.1.1 to 5.4.1 by downloading new version exporting and replacing Lib folder for graddle.

    I added script AndroidPostBuildProcessor > to Editor folder
    I downloaded and Updated Play services to 1.2.135.0
    Unity I am using is 2018.4.12f1
    I disabled Instalation inside of resolver settings for Android
    I deleted all all ready libraries in Android folder from google play.services.support ..... what ever was there from google
    I created main template
    I updated build from 3.4.0 to classpath 'com.android.tools.build:gradle:3.5.2'
    I added this in dependencies since I am using IronSource mediation and I needed to make Admob to work
    implementation 'com.google.android.gms:play-services-ads:18.2.0'
    implementation group: 'com.google.android.gms', name: 'play-services-basement', version: '17.1.1'
    implementation group: 'com.google.android.gms', name: 'play-services-ads-identifier', version: '17.0.0'

    This way I am downloading explicitly this libraries for mediation
    In Play services settings I ticked ON path to mainTemplate

    I clicked force resolve but seamed like nothing hapened maybe it did no idea.. didn't check mainTemplate I went for build and run
    And finally it managed to build!!!

    After build this is my mainTemapate

    Code (CSharp):
    1. // GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN
    2.  
    3. buildscript {
    4.     repositories {
    5.         mavenCentral()
    6.         google()
    7.         jcenter()
    8.     }
    9.  
    10.     dependencies {
    11.         classpath 'com.android.tools.build:gradle:3.5.2'
    12. **BUILD_SCRIPT_DEPS**}
    13. }
    14.  
    15. allprojects {
    16.     repositories {
    17.         mavenCentral()
    18.         google()
    19.         jcenter()
    20.         flatDir {
    21.             dirs 'libs'
    22.         }
    23.     }
    24. }
    25.  
    26. // Android Resolver Repos Start
    27. ([rootProject] + (rootProject.subprojects as List)).each { project ->
    28.     project.repositories {
    29.         def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/")
    30.         maven {
    31.             url "https://maven.google.com"
    32.         }
    33.         mavenLocal()
    34.         jcenter()
    35.         mavenCentral()
    36.     }
    37. }
    38. // Android Resolver Repos End
    39. apply plugin: 'com.android.application'
    40. **APPLY_PLUGINS**
    41.  
    42. dependencies {
    43.     implementation fileTree(dir: 'libs', include: ['*.jar'])
    44.     implementation 'com.google.android.gms:play-services-ads:18.2.0'
    45.     implementation group: 'com.google.android.gms', name: 'play-services-basement', version: '17.1.1'
    46.     implementation group: 'com.google.android.gms', name: 'play-services-ads-identifier', version: '17.0.0'
    47.  
    48. // Android Resolver Dependencies Start
    49.     implementation 'com.android.support:appcompat-v7:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
    50.     implementation 'com.android.support:cardview-v7:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
    51.     implementation 'com.android.support:customtabs:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
    52.     implementation 'com.android.support:support-v4:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
    53.     implementation 'com.facebook.android:facebook-applinks:[5,6)' // Assets/FacebookSDK/Plugins/Editor/Dependencies.xml:6
    54.     implementation 'com.facebook.android:facebook-core:[5,6)' // Assets/FacebookSDK/Plugins/Editor/Dependencies.xml:5
    55.     implementation 'com.facebook.android:facebook-login:[5,6)' // Assets/FacebookSDK/Plugins/Editor/Dependencies.xml:7
    56.     implementation 'com.facebook.android:facebook-share:[5,6)' // Assets/FacebookSDK/Plugins/Editor/Dependencies.xml:8
    57.     implementation 'com.parse.bolts:bolts-android:1.4.0' // Assets/FacebookSDK/Plugins/Editor/Dependencies.xml:4
    58. // Android Resolver Dependencies End
    59. **DEPS**}
    60.  
    61. // Android Resolver Exclusions Start
    62. android {
    63.   packagingOptions {
    64.       exclude ('/lib/armeabi/*' + '*')
    65.       exclude ('/lib/mips/*' + '*')
    66.       exclude ('/lib/mips64/*' + '*')
    67.       exclude ('/lib/x86/*' + '*')
    68.       exclude ('/lib/x86_64/*' + '*')
    69.   }
    70. }
    71. // Android Resolver Exclusions End
    72. android {
    73.     compileSdkVersion **APIVERSION**
    74.     buildToolsVersion '**BUILDTOOLS**'
    75.  
    76.     compileOptions {
    77.         sourceCompatibility JavaVersion.VERSION_1_8
    78.         targetCompatibility JavaVersion.VERSION_1_8
    79.     }
    80.  
    81.     defaultConfig {
    82.         minSdkVersion **MINSDKVERSION**
    83.         targetSdkVersion **TARGETSDKVERSION**
    84.         applicationId '**APPLICATIONID**'
    85.         ndk {
    86.             abiFilters **ABIFILTERS**
    87.         }
    88.         versionCode **VERSIONCODE**
    89.         versionName '**VERSIONNAME**'
    90.     }
    91.  
    92.     lintOptions {
    93.         abortOnError false
    94.     }
    95.  
    96.     aaptOptions {
    97.         noCompress = ['.unity3d', '.ress', '.resource', '.obb'**STREAMING_ASSETS**]
    98.     }**SIGN**
    99.  
    100.     buildTypes {
    101.         debug {
    102.             minifyEnabled **MINIFY_DEBUG**
    103.             useProguard **PROGUARD_DEBUG**
    104.             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'**USER_PROGUARD**
    105.             jniDebuggable true
    106.         }
    107.         release {
    108.             minifyEnabled **MINIFY_RELEASE**
    109.             useProguard **PROGUARD_RELEASE**
    110.             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'**USER_PROGUARD****SIGNCONFIG**
    111.         }
    112.     }**PACKAGING_OPTIONS****SPLITS**
    113. **BUILT_APK_LOCATION**
    114.     bundle {
    115.         language {
    116.             enableSplit = false
    117.         }
    118.         density {
    119.             enableSplit = false
    120.         }
    121.         abi {
    122.             enableSplit = true
    123.         }
    124.     }
    125. }**SPLITS_VERSION_CODE****REPOSITORIES****SOURCE_BUILD_SETUP**
    126.  
     
  11. newlife

    newlife

    Joined:
    Jan 20, 2010
    Posts:
    1,080
    Thank you @tummygames! your fix to **DIR_UNITYPROJECT** issue on windows (slash instead of backslash in path) is perfect :)
     
  12. etig

    etig

    Joined:
    Feb 15, 2015
    Posts:
    11
    Hi @tummygames,
    How do you disabled it?
     
  13. giangnguyenappscyclone

    giangnguyenappscyclone

    Joined:
    May 3, 2017
    Posts:
    4
    to me,
    I delete all libs in Asset/Plugin/Android
    after that, Open android setting by menu Assets/Play Service Resolver/ Android Resolver/ Setting
    Click Restore default and enable Jetifier, Click OK
    It will Resolve all android X lib (see the image), and build OK

    hope useful
     

    Attached Files:

  14. Jumeuan

    Jumeuan

    Joined:
    Mar 14, 2017
    Posts:
    39
    On Unity 2019 , you must modify Atom's code to build success:

    Code (CSharp):
    1. void IPostGenerateGradleAndroidProject.OnPostGenerateGradleAndroidProject(string path)
    2.     {
    3.         Debug.Log("Bulid path : " + path);
    4.         // This line need modify, to replace new path of gradle
    5.         string gradlePropertiesFile = path.Replace("unityLibrary", "") + " /gradle.properties";
    6.         if (File.Exists(gradlePropertiesFile))
    7.         {
    8.             File.Delete(gradlePropertiesFile);
    9.         }
    10.         StreamWriter writer = File.CreateText(gradlePropertiesFile);
    11.         writer.WriteLine("org.gradle.jvmargs=-Xmx4096M");
    12.         writer.WriteLine("android.useAndroidX=true");
    13.         writer.WriteLine("android.enableJetifier=true");
    14.         writer.Flush();
    15.         writer.Close();
    16.  
    17.     }
     
    munkiki7 and DanilLetov like this.
  15. Starbox

    Starbox

    Joined:
    Sep 17, 2014
    Posts:
    467
    I did the same. I used the "enhanced" version as edited by Jumeuan. I had a bug where the path of Gradle's output had a single blank space right before /gradle.properties (I had not edited that line so I was puzzled as to why this happened).

    I use the last version as of today, or at least a very recent one.

    2019.2.15f1

    Ok, did that too. We're talking about "install android packages", right?

    I may need some clarification on this. I use several ad SDKs that have put stuff in this folder. There are several "libs" folders, either right after /Android/ or one folder deeper.
    Are these folders to be deleted, including the libs folders that are inside those named after the advertising companies?
    I'm not sure they'll be able to reimport the libs after this even if I try to resolve anything.

    Yes, that file appears when we ask for a custom gradle build. Unticking the box does not delete the file, merely appends a DISABLED extension to its name (not a problem, just pointing this out for those who might read this and be wondering what goes on).

    Now that's something I don't understand. What does that mean and how did you do that?

    How did you know that you had to add these specifically?
    I have several SDKs that may need to be told to do something similar, and it's possible some other plugins may need a similar guidance to allow a gradle-build to be done properly.
    How do you define what needs to be added?
    And you added them to the mainTemplate.gradle file, correct?

    I suppose it's a typo and you meant 'patch mainTemplate'?
    (Today, now we use External Dependencies Manager which provides the same options and more.)

    I hope I'll experience the same positive outcome.

    I obviously can't copy/paste your mainTemplate either but I'll compare mine and yours, if all of this works.
     
  16. bitterness

    bitterness

    Joined:
    Sep 19, 2013
    Posts:
    14
    Necroing this, but just wanted to say thanks! I'd been banging my head against the wall trying to work this junk out (Unity 2019.4.40f1). The Play Resolver actually has a tickbox for using Jetifier now and I noticed it added this to my mainTemplate.gradle:

    which I thought would fix the problem, but nothing actually changed! Once I used the post-build script above everything worked. My Frankenstein's monster-esque hacked together "one workaround after another to get an Android build working" project lives to fight another day! Cheers :)
     
  17. Voxel-Busters

    Voxel-Busters

    Joined:
    Feb 25, 2015
    Posts:
    1,963
    If the old support library is used by a specific plugin, reach out the publisher of it and ask them to update to androidx. v24 support libraries are pretty old and actually migrating to androidx isn't a big issue for the publisher.

    The main reason for this recommendation is it got introduced in 2018 and now its 2022 which has valid timeline for migration.
     
  18. Niter88

    Niter88

    Joined:
    Jul 24, 2019
    Posts:
    112
    That's the ultimate solution. It works!
    I tried everything before that, including copying the appCompat lib to my plugins (which most said is the solution, it's not)
     
  19. Starbox

    Starbox

    Joined:
    Sep 17, 2014
    Posts:
    467
    But isn't ... wait... Jetifier supposed to bridge the old and new, notably to properly resolve dependencies that rely on older stuff? Is Jetifier largely useless or what?
     
  20. Voxel-Busters

    Voxel-Busters

    Joined:
    Feb 25, 2015
    Posts:
    1,963
    True. If you have both old support libraries and androidx libraries within your project, jetifier is supposed to transform old support libs to androidx during build time.

    This needs setup in unity(enable useAndroidX, jetifier flags)in gradle properties file. However, it's not a tough one to migrate to androidx for the owner of the plugin.
     
    Niter88 likes this.