天天看點

Unity build時, Temp\StagingArea\android-libraries\unity-android-resources targetSdkVersion='26' 報錯

最近在使用unity2017時,因管道方要求,給出的包必須要是target21,在直接修改了buildsetting中的target APILevel為21後,然後将項目的androidmainfest的targetsdkversion設定為21,打包時出現了如下報錯。

[Temp\StagingArea\AndroidManifest-main.xml:2, \Temp\StagingArea\android-libraries\unity-android-resources\AndroidManifest.xml:1] Main manifest has <uses-sdk android:targetSdkVersion='21'> but library uses targetSdkVersion='26'      

temp檔案夾是在unity編譯的時候自動生成的臨時檔案。因為unity在打包過程中會自動合并所有plugins目錄下的androidmainfest生成一個唯一的androidmainfest。對于合并後的唯一的targetsdkversion的設定,首先取決于buildsetting中的target APILevel,其次是androidmainfest中的設定。

比如我設定了buildsetting中的target APILevel為21,而我有一個androidmainfest的taegetsdk為26,就會出現以上報錯。高版本無法和低版本合并。

但我的項目中隻存在一個androidmainfest,且設定為21,但仍出現了已上報錯。于是我打開了報錯資訊中的\Temp\StagingArea\android-libraries\unity-android-resources\路徑,發現在項目編譯的時候,在這個路徑下自動生成了一個androidmainfest。且裡面隻存在一句話: <uses-sdk android:targetSdkVersion="26" />。

正是因為這個生成的androidmainfest裡的設定targetsdk版本過高導緻了無法合并。是以我去unity官網查詢了unity-android-resources這個編譯時生成的目錄。

官網對這個目錄的生成有着詳細的解釋 : Unity必須将plugins目錄下的'res'檔案夾中的所有檔案建構到一個插件中。該插件稱為unity-android-resources,簡而言之就是當出包的時候,如果plugins/android目錄下存在res這個檔案夾,unity就會為了編譯這個檔案夾中的資源将它當做一個插件來調用,就将res中的檔案編譯成一個叫做unity-android-resources的檔案,自動為它生成一個androidmainfest,裡面預設的targetsdkversion是26。這個可以說是unity的bug

但官網并不鼓勵這種在plugins/android目錄下直接放res檔案夾,稱這是已經被棄用的功能。但是現在時間緊迫,我也不可能為了出包就删掉這個res目錄,是以經過一番研究,發現了針對這個問題的幾個解決辦法:

1.res目錄之是以存在是因為項目中使用的某些jar包需要去調用它,而在某個版本的unity之後,官網鼓勵開發者去使用aar包來代替jar包,而aar包最大的好處就在于可以直接将資源也放進去,當我們使用androidstudio去打出一個aar包,就可以直接将res檔案設定好,打出的aar包中自然就帶上了res檔案,那麼unity就不需要存在這個檔案夾了。具體aar包的出法這裡不再解釋,網上有很多資料。

2.unity在編譯unity-android-resources時之是以預設是26,是因為我們沒有對他進行設定,而具體設定是辦法就是,在res這個目錄下建立出一個檔案叫做project.properties。(随便建立一個文本文檔改字尾名就可以),然後再這個檔案裡的内容是

target = android-21

android.library = true

這樣的話在每次打包時就會将生成的androidmainfest設定為21,也可以根據自己的實際情況來設定targte的值。這樣就能完美解決這個問題了。

補充:發現這種方法在unity的build system為internal時不會起效,隻會在build system為gradle時會被編譯後起效。

3.當我們使用gradle出包時,将target APILevel設定為最高忽略掉這個問題,并在最後的gradle.build檔案中去處理targetsdk的設定,這樣可以完美避免以上情況。具體的步驟已經有大佬給出

https://blog.csdn.net/geoffyan/article/details/79761051

4.出于某種gradle編譯後的bug,導緻我無法使用gradle打出可以使用的工程,這時仍要使用internal去編譯解決問題。是以我還是推薦使用aar包來解決該問題。(如果res目錄并不重要,可以直接删除掉res目錄來避免這個問題)。