Android Gradle Plug 4.1. 0 Failure to get manifest location after Android Gradle Plug 4.1. 0 Upgrade

  • 2021-12-09 10:03:43
  • OfStack

Problem background

In the process of project compilation, gradle plug-in similar to Android Gradle Plugin is used for compilation, and manifest file will be dynamically modified when apk is finally packaged.

Recently, it was found that online users responded to upgrade to the following development environment, and there was no configuration in manifest file after packaging apk.


Android Gradle Plugin:4.1.0
Gradle:6.5
Android Studio:4.1

Confirm the direction of investigation

First of all, we should confirm which of the above three upgrades caused the problem.

The environment upgrade process locally verified the following conclusions:

Android Gradle Plugin: 4.1. 0 Mandatory Android Studio: 4.1 + Gradle: 6.5. However, the packaging process is normal in the following environments:


Android Gradle Plugin:4.0.2
Gradle:6.5
Android Studio:4.1

Android Gradle Plugin: 4.0. 2 is the previous version of 4.1, so it can be confirmed that the incompatibility problem is caused by the upgrade of Android Gradle Plugin: 4.1. 0.

Clear the direction of the investigation, and then we can have a definite object in view.

Investigation and analysis

Our gradle plug-in is processed after obtaining the manifest file through the following code:


new File(output.processManifestProvider.get().manifestOutputDirectory.get().getAsFile(), "AndroidManifest.xml")

In fact, it is not so simple, but this sentence is the most critical. After adding a few key print statements to the gradle plug-in, you get the following error during compilation:

Could not get unknown property 'manifestOutputDirectory' for task ':app:processDebugManifest' of type com.android.build.gradle.tasks.ProcessMultiApkApplicationManifest

Baidu has made one visit, but there is no relevant record. After all, it has only been two months since Android Gradle Plugin: 4.1. 0 was officially released, so it has to be self-sufficient.

Obviously, the attribute of reading manifest file location is invalid, and the most direct method is to look at the source code. Just look at the Android Gradle Plugin: 4.1. 0 jar package.

It's Baidu 1 again. Unfortunately, there is no download address.

Search on JCenter, and the JCenter warehouse is only updated to 2. x version.

Yes, it seems that since Android Studio 3.0, google has transferred Android Gradle Plugin to google () warehouse, so I can only go to google () warehouse, and I don't know the specific address at 1:30. I didn't pay attention to the compilation log output of studio in the previous compilation process. Of course, if it is a brand-new engineering environment, compile 1.

Try your luck under the cache path of AS first, but you must have a direction before you try your luck. Don't forget the classpath configuration of Android Gradle Plugin:


classpath 'com.android.tools.build:gradle:4.1.0'

Sure enough, I found it in the following path:

/Users/jackie/.gradle/caches/modules-2/files-2.1/com.android.tools.build/gradle

Loaded all kinds of versions have, directly get 4.1. 0 jar package to see the source code, in ProcessMultiApkApplicationManifest. class found the following code:


File mergedManifestOutputFile = new File(((Directory)getMultiApkManifestOutputDirectory().get()).getAsFile(), 
  FileUtils.join(new String[] { dirName, 
    "AndroidManifest.xml" }));

There is also an abstract method:


public abstract DirectoryProperty getMultiApkManifestOutputDirectory();

It seems that the attribute has become multiApkManifestOutputDirectory.

If not, let's look at the source for 4.0. 2 and find the following code in ProcessApplicationManifest. class:

File manifestOutputFile = new File(((Directory)getManifestOutputDirectory().get()).getAsFile(), FileUtils.join(new String[] { apkData.getDirName(), "AndroidManifest.xml" }));

Obviously, in version 4.0. 2, the attribute to get the manifest file path was indeed manifestOutputDirectory, and task was essentially an instance of ProcessApplicationManifest, but since version 4.1. 0, task has become an instance of ProcessMultiApkApplicationManifest and the attribute has become multiApkMnifestOutputDirectory.

Ok, the rest is to make version 1 compatible, and you are done.

new File(output.processManifestProvider.get().multiApkManifestOutputDirectory.get().getAsFile(), "AndroidManifest.xml")

Summarize

Most of the compilation scripts based on gradle work in one way, that is, writing a custom task, doing custom special treatment before or after a preset task, etc., and the more advanced gradle plug-in is no exception.

Android Gradle Plugin is also only an gradle plug-in officially developed by Google. Each upgrade version will be accompanied by one update of "task name change", "task processing content change", "task execution sequence change", etc. These updates will probably affect our gradle plug-ins which are specially treated based on their "preset task", so most version compatibility issues should be

In addition, sometimes the upgrade of Gradle will bring some compatibility problems.


Related articles: