Migrating a Cordova Android project to AndroidX

14,736

Solution 1

Just read that : https://cordova.apache.org/announcements/2020/06/29/cordova-android-9.0.0.html

To be sure :

  • Clear your gradle cache directory (in home/.gradle/caches)
  • Remove and add the android platform
  • Check your requirement following the above article ones

Then :

Add the following in your config.xml :

<preference name="AndroidXEnabled" value="true" />
<preference name="GradlePluginKotlinEnabled" value="true" />
<preference name="GradlePluginKotlinCodeStyle" value="official" />
<preference name="GradlePluginKotlinVersion" value="1.3.50" />

(AndroidXEnabled preference add jetifyer and androidX in the gradle.properties)

And your build should now works

Solution 2

For the benefit of anyone who runs into this thread - if you have a Cordova app with several third party plugins you are probably better off using the dpa99 androidx adapter that I mention above. If, like me, you only rely on your own plugin switching to using AndroidX in place of the old style Android support libraries is easy.

Step 1

In path/to/project/platforms/android create a file named build-extras.gradle and edit it to contain the following

android.useAndroidX=true
android.enableJetifier=false

The first line is self explanatory. To understand enableJetifier consider first this statement

The standalone Jetifier tool migrates support-library-dependent libraries to rely on the equivalent AndroidX packages instead.

in the Google documentation. Given that you are considering spinning your own because you do not use other, external, Cordova plugins you do not need to enable Jetifier.

Step 2

With this done all that is left to do is to replace

<framework src="com.android.support:appcompat-v7:28.0.0" />

in your own plugin.xml file with

<framework src="androidx.appcompat:appcompat:1.0.0" />

Step 3

Finally proceed to replace any older native Android libraries - e.g. Play Services Ads - that you are currently using with the latest versions which now use AndroidX. Now run cordova build android and you have completed the transition!

Share:
14,736

Related videos on Youtube

DroidOS
Author by

DroidOS

Updated on June 04, 2022

Comments

  • DroidOS
    DroidOS almost 2 years

    I am currently testing a hybrid Cordova/Android app with AdMob test ads. The app uses one custom - i.e. in-house - plugin from which I access the Google Play Services AdMob API. The relevant bits of the plugin.xml file are as follows

    <platform name="android">
     <preference name="PLAY_SERVICES_VERSION" default="17.2.0"/>
     <preference name="ADMOB_APP_ID" default="ca-app-pub-...."/>
    
     <framework src="com.android.support:appcompat-v7:27.1.0" />
     <framework src="com.google.android.gms:play-services-ads:17.2.0"/>
    

    The config.xml file for the app declares the following

     <preference name="android-minSdkVersion" value="23" />
     <preference name="android-targetSdkVersion" value="28" />
    

    The Java code to load and show rewarded video ads follows the discussion here.

    While this works what bothers me here is that I am using a rather ancient play-services-ads API. The problem is that if I try to upgrade to the latest API according to the instructions shown here. My modified plugin.xml file reflecting the changes needed to use the latest APIs

    <platform name="android">
      <preference name="PLAY_SERVICES_VERSION" default="18.3.0"/>
      <preference name="ADMOB_APP_ID" default="ca-app-pub-..."/>
    
      <framework src="com.android.support:appcompat-v7:28.0.0" />
      <framework src="com.google.android.gms:play-services-ads:18.3.0"/>
    

    The problem is that I am no longer able to compile the app. Cordova CLI reports a string of issues which I show below

    iled with exit code 1 Error output: Note: path\to\app\platforms\android\CordovaLib\src\org\apache\cordova\engine\SystemCookieManager.java uses or overrides a deprecated API. Note: Recompile with -Xlint:deprecation for details. path\to\app\platforms\android\app\src\main\AndroidManifest.xml:22:18-86 Error: Attribute application@appComponentFactory value=(androidx.core.app.CoreComponentFactory) from [androidx.core:core:1.0.0] AndroidManifest.xml:22:18-86 is also present at [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91 value=(android.support.v4.app.CoreComponentFactory). Suggestion: add 'tools:replace="android:appComponentFactory"' to element at AndroidManifest.xml:4:5-21:19 to override.

    FAILURE: Build failed with an exception.

    • What went wrong: Execution failed for task ':app:processDebugManifest'.

      Manifest merger failed : Attribute application@appComponentFactory value=(androidx.core.app.CoreComponentFactory) from [androidx.core:core:1.0.0] AndroidManifest.xml:22:18-86 is also present at [com.android.support:support-compat:28.0.0] AndroidManifest.xml:22:18-91 value=(android.support.v4.app.CoreComponentFactory). Suggestion: add 'tools:replace="android:appComponentFactory"' to element at AndroidManifest.xml:4:5-21:19 to override.

    I narrowed down the problem to gms:play-services-ads which appears to pull in androidx libraries that are not compatible with the old style android libraries. The helpful suggestion from Gradle above - ** add tools:replace="android:appComponentFactory ** did not help since the tools:replace attribute of the application node was not recognized.

    The solution I have implemented that has worked is as follows

    • I created a build-extras.gradle file under path/to/myapp/platforms/android with the lines

      android.useAndroidX=true android.enableJetifier=true

    • As a stopgap I used this plugin which deals with the incompatibilities between androidx and android libraries. While this works I am not too keen on using additional plugins. I suspect all this plugin does is ensure that the AndroidManifest.xml is correct but I am unable to see how. I'd be most grateful to anyone who might be able to explain what needs to be done to get things to work without additional plugins.

  • dev-jim
    dev-jim almost 3 years
    for all the solution out there, this is the only one that works. But for me, I just added npmjs.com/package/cordova-plugin-androidx-adapter plugin and it works like a charm
  • andreszs
    andreszs about 2 years
    As expected, the androidx-adapter plugin is quite useless. Adding the androidx framework as you pointed out to a plugin.xml solved the build problems, thank you sir.
  • DroidOS
    DroidOS about 2 years
    I am surprised that there are still people using Cordova. Cordova was good in its time but has lost steam now. There are far better options