Migrating a Cordova Android project to AndroidX

DroidOS picture DroidOS · Dec 20, 2019 · Viewed 10.1k times · Source

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.

Answer

Lucas  picture Lucas · Jan 27, 2021

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