Android Gradle Plug 4.1.0 升級後gradle獲取manifest位置失敗問題解決
問題背景
專案編譯過程中,使用了類似Android Gradle Plugin的gradle外掛進行編譯,在最終打包apk時,會動態修改manifest檔案。
近期發現線上使用者有反應升級到以下開發環境後,打包apk後manifest檔案中沒有應有的任何配置。
Android Gradle Plugin:4.1.0 Gradle:6.5 Android Studio:4.1
確認調查方向
首先要確認清楚到底是上述3個哪個的升級導致的問題。
在本地進行環境升級過程驗證了以下結論:
Android Gradle Plugin:4.1.0 強制要求 Android Studio:4.1 + Gradle:6.5。然而 以下環境下打包過程是正常的:
Android Gradle Plugin:4.0.2 Gradle:6.5 Android Studio:4.1
Android Gradle Plugin:4.0.2 是 4.1 的前一個版本,至此可以確認是 Android Gradle Plugin:4.1.0 的升級導致的不相容問題。
明確了調查的方向,接下來就可以有的放矢了。
調查分析
我們的gradle外掛,是通過以下程式碼獲取到manifest檔案後做處理的:
new File(output.processManifestProvider.get().manifestOutputDirectory.get().getAsFile(),"AndroidManifest.xml")
其實並非如此簡單,只是這一句是最關鍵的。在gradle外掛中增加了一些關鍵列印語句後,編譯過程中得到了以下錯誤提示:
Could not get unknown property 'manifestOutputDirectory' for task ':app:processDebugManifest' of type com.android.build.gradle.tasks.ProcessMultiApkApplicationManifest
百度了一下,沒有任何相關記錄,畢竟距離 Android Gradle Plugin:4.1.0 正式釋出才過去2個月,只好自給自足。
很明顯是讀取manifest檔案位置的屬性失效了,那最直接的方法就是看原始碼。找到 Android Gradle Plugin:4.1.0 的jar包看看就行。
又是百度一下,很可惜,沒有下載地址。
上JCenter找,結果JCenter倉庫只更新到2.x版本。
也對,好像是從 Android Studio 3.0 開始,google就將 Android Gradle Plugin 轉移至 google() 倉庫了,那隻能去 google() 倉庫找了,一時半會也不知道具體地址,以前的編譯過程中也沒留意看studio的編譯日誌輸出,當然如果是一個全新工程環境,編譯一下,肯定能找到倉庫地址的,不過我懶得搞。
先到AS的快取路徑下碰碰運氣吧,不過碰運氣也得先有個方向,別忘了Android Gradle Plugin的classpath配置:
classpath 'com.android.tools.build:gradle:4.1.0'
果不其然,在以下路徑找到了:
/Users/jackie/.gradle/caches/modules-2/files-2.1/com.android.tools.build/gradle
載入過的各種版本都有,直接拿到 4.1.0 的jar包看原始碼,在 ProcessMultiApkApplicationManifest.class 中找到了以下程式碼:
File mergedManifestOutputFile = new File(((Directory)getMultiApkManifestOutputDirectory().get()).getAsFile(),FileUtils.join(new String[] { dirName,"AndroidManifest.xml" }));
同時還有一個抽象方法:
public abstract DirectoryProperty getMultiApkManifestOutputDirectory();
看來屬性已經變成了 multiApkManifestOutputDirectory。
如果不確定,我們再看看 4.0.2 的原始碼,在 ProcessApplicationManifest.class 中找到了以下程式碼:
複製程式碼 程式碼如下:File manifestOutputFile = new File(((Directory)getManifestOutputDirectory().get()).getAsFile(),FileUtils.join(new String[] { apkData.getDirName(),"AndroidManifest.xml" }));
很明顯,在 4.0.2 版本時,獲取manifest檔案路徑的屬性確實是 manifestOutputDirectory ,而task本質上是一個 ProcessApplicationManifest 例項,但從 4.1.0 版本開始, task變為 ProcessMultiApkApplicationManifest 的例項,屬性變為 multiApkMnifestOutputDirectory 了。
好了,剩下的就是做一下版本相容了,大功告成。
複製程式碼 程式碼如下:new File(output.processManifestProvider.get().multiApkManifestOutputDirectory.get().getAsFile(),"AndroidManifest.xml")
總結
大部分基於gradle的編譯指令碼,其工作原理都一樣,就是在編寫自定義的task、在某個預設的task之前或之後做自定義的特殊處理等等,更高階一點的gradle外掛也不例外。
而 Android Gradle Plugin 同樣也只是一個Google官方開發的gradle外掛,每次升級版本都會伴隨著一些“task名變更”、“task處理內容變更”、“task執行順序變更”等等的更新,這些更新很可能就會影響到我們這些基於其“預置task”做特殊處理的gradle外掛,所以大部分版本相容問題都應該從這個方向出發調查。
另外,有時候Gradle的升級也會帶來一些相容問題。
到此這篇關於Android Gradle Plug 4.1.0 升級後gradle獲取manifest位置失敗問題解決的文章就介紹到這了,更多相關Android Gradle4.1升級內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!