Unity app提高设备可用性
/
支持 64 位架構(gòu)
自?2019 年 8 月 1 日起,您在 Google Play 上發(fā)布的應(yīng)用必須支持?64 位架構(gòu)。 64 位 CPU 能夠為您的用戶提供更快、更豐富的體驗。添加 64 位的應(yīng)用版本不僅可以提升性能、為未來創(chuàng)新創(chuàng)造條件,還能針對僅支持 64 位架構(gòu)的設(shè)備做好準(zhǔn)備。
本指南介紹了如何確保 32 位應(yīng)用為支持 64 位設(shè)備做好準(zhǔn)備,供您隨時采用。
評估您的應(yīng)用
如果您的應(yīng)用僅使用以 Java 編程語言或 Kotlin 編寫的代碼(包括所有庫或 SDK),那么就表示該應(yīng)用已經(jīng)能支持 64 位設(shè)備。如果您的應(yīng)用使用了任何原生代碼,或者您不確定應(yīng)用是否使用了這類代碼,那么您需要評估應(yīng)用并采取措施。
快速狀態(tài)檢查
要檢查應(yīng)用是否已滿足 64 位要求,一種便捷的方法是前往 Play 管理中心查看現(xiàn)有的版本,確定應(yīng)用是否合規(guī):
?如果您的草稿版本存在與 64 位要求相關(guān)的問題,Play 管理中心也會顯示相應(yīng)的警告。請看以下示例:
如果您看到提醒,請按照提醒下面的步驟操作,讓應(yīng)用做好支持 64 位的準(zhǔn)備。
您的應(yīng)用是否使用了原生代碼?
首先需要檢查您的應(yīng)用是否使用了任何原生代碼。 如果您的應(yīng)用符合以下情況,便是使用了原生代碼:
- 使用了任何 C/C++(原生)代碼。
- 與任何第三方原生庫關(guān)聯(lián)。
- 通過使用原生庫的第三方應(yīng)用構(gòu)建程序構(gòu)建而成。
應(yīng)用是否包含 64 位庫?
若要確定應(yīng)用是否包含 64 位庫,最簡單的方法就是檢查 APK 文件的結(jié)構(gòu)。在構(gòu)建時,APK 會與應(yīng)用所需的所有原生庫打包在一起。原生庫會根據(jù)?ABI?存儲在不同的文件夾中。您的應(yīng)用不一定要支持所有 64 位架構(gòu),但對于支持的每種原生 32 位架構(gòu),應(yīng)用都必須包含相應(yīng)的 64 位架構(gòu)。
對于?ARM 架構(gòu),32 位庫位于?armeabi-v7a?中。 對應(yīng)的 64 位庫則位于?arm64-v8a?中。
對于 x86 架構(gòu),32 位庫位于?x86?中,64 位庫則位于?x86_64?中。
首先要確保這兩個文件夾中都有原生庫??偨Y(jié)如下:
| ARM | lib/armeabi-v7a | lib/arm64-v8a |
| x86 | lib/x86 | lib/x86_64 |
請注意,每個文件夾中的一套庫可能完全相同,也可能不完全相同,這取決于應(yīng)用的具體情況。您應(yīng)達(dá)到的目標(biāo)是確保您的應(yīng)用能夠在僅支持 64 位架構(gòu)的環(huán)境中正常運(yùn)行。
通常情況下,同時針對 32 位和 64 位架構(gòu)構(gòu)建的 APK 或軟件包會具有這兩種 ABI 的文件夾,每個文件夾中都有一套相應(yīng)的原生庫。如果您的應(yīng)用不支持 64 位架構(gòu),那么您很可能會看到 32 位 ABI 文件夾,但沒有 64 位文件夾。
使用 APK 分析器查找原生庫
APK 分析器是一款可用于對所構(gòu)建的 APK 進(jìn)行各方面評估的工具。針對我們目前所討論的情況,我們將使用該工具查找原生庫,以確定是否具備 64 位庫。
從菜單中依次選擇?Build > Analyze APK…
選擇您要評估的 APK。
查看?lib?文件夾,您可以在其中找到“.so”文件。如果在您的應(yīng)用中找不到任何“.so”文件,則說明該應(yīng)用已支持 64 位架構(gòu),您無需采取進(jìn)一步措施。如果您看到?armeabi-v7a?或?x86,則說明您有 32 位庫。
檢查是否?arm64-v8a?或?x86_64?文件夾中有類似的“.so”文件。
如果您沒有任何?arm64-v8a?或?x86_64?庫,則需要更新構(gòu)建流程以開始構(gòu)建并打包 APK 中的這些工件。
如果您看到 32 位和 64 位的庫均已打包到軟件包中,則可以跳至在 64 位硬件上測試應(yīng)用。
通過解壓縮 APK 查找原生庫
APK 文件的結(jié)構(gòu)類似于 ZIP 文件,可以像 ZIP 文件一樣解壓縮。 如果您更喜歡使用命令行或任何其他解壓縮工具,也可以采用解壓縮 APK 的方法。
只需解壓縮 APK 文件(根據(jù)您使用的解壓縮工具,您可能需要將其重命名為 .zip),然后按照上文中的指南瀏覽解壓縮后的文件,即可確定您的應(yīng)用是否已經(jīng)為支持 64 位設(shè)備做好準(zhǔn)備了。
例如,您可以從命令行中運(yùn)行如下命令:
:: Command Line > zipinfo -1 YOUR_APK_FILE.apk | grep \.so$ lib/armeabi-v7a/libmain.so lib/armeabi-v7a/libmono.so lib/armeabi-v7a/libunity.so lib/arm64-v8a/libmain.so lib/arm64-v8a/libmono.so lib/arm64-v8a/libunity.so請注意,此示例中存在?armeabi-v7a?庫和?arm64-v8a?庫,這表明該應(yīng)用支持 64 位架構(gòu)。
使用 64 位庫構(gòu)建應(yīng)用
下面針對構(gòu)建 64 位庫做出了相關(guān)的說明。不過,需要指出的是,以下內(nèi)容僅介紹了如何構(gòu)建在源代碼的基礎(chǔ)上可構(gòu)建的代碼和庫。
如果您使用任何外部 SDK 或庫,請確保按照上文所述的步驟使用 64 位版本。如果沒有 64 位版本可用,請與相應(yīng) SDK 或庫的所有者聯(lián)系,并在規(guī)劃支持 64 位設(shè)備的方案時將這一點(diǎn)考慮在內(nèi)。
使用 Android Studio 或 Gradle 進(jìn)行構(gòu)建
大多數(shù) Android Studio 項目都使用 Gradle 作為底層構(gòu)建系統(tǒng),因此本部分適用于使用這兩種工具進(jìn)行構(gòu)建的情況。針對原生代碼進(jìn)行構(gòu)建很簡單,只需將?arm64-v8a?和/或?x86_64(視您要支持的架構(gòu)而定)添加到應(yīng)用的“build.gradle”文件中的?ndk.abiFilters?設(shè)置中即可:
// Your app's build.gradle plugins {id 'com.android.app' }android {compileSdkVersion 27defaultConfig {appId "com.google.example.64bit"minSdkVersion 15targetSdkVersion 28versionCode 1versionName "1.0"ndk.abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64' // ...使用 CMake 進(jìn)行構(gòu)建
如果您的應(yīng)用是使用?CMake?構(gòu)建的,那么您可以通過將?arm64-v8a?傳遞到“-DANDROID_ABI”參數(shù)來針對 64 位 ABI 進(jìn)行構(gòu)建:
:: Command Line > cmake -DANDROID_ABI=arm64-v8a … or > cmake -DANDROID_ABI=x86_64 …在使用?externalNativeBuild?時,此方法無效。請參閱使用 Gradle 進(jìn)行構(gòu)建部分。
使用 ndk-build 進(jìn)行構(gòu)建
如果您的應(yīng)用是使用?ndk-build?構(gòu)建的,那么您可以使用?APP_ABI?變量修改“Application.mk”文件,從而針對 64 位 ABI 進(jìn)行構(gòu)建:
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64在使用?externalNativeBuild?時,此方法無效。請參閱使用 Gradle 進(jìn)行構(gòu)建部分。
將 32 位代碼移植到 64 位架構(gòu)
如果您的代碼已經(jīng)可以在桌面或 iOS 平臺上運(yùn)行,那么您無需針對 Android 做額外的工作。如果這是第一次針對 64 位系統(tǒng)構(gòu)建您的代碼,那么您需要解決的主要問題是指針不再適合?int?這樣的 32 位整數(shù)類型。您將需要更新以?int、unsigned?或?uint32_t?等類型存儲指針的代碼。在 Unix 系統(tǒng)上,long?對應(yīng)的是指針大小,但在 Windows 上并非如此,因此您應(yīng)該改用釋意類型?uintptr_t?或?intptr_t。使用?ptrdiff_t?類型來存儲兩個指針之間的差異。
您應(yīng)該始終選擇使用?<stdint.h>?中定義的特定固定寬度整數(shù)類型,而不是?int?或?long?等傳統(tǒng)類型,即便對于非指針也應(yīng)如此。
使用以下編譯器標(biāo)記來捕捉代碼在指針和整數(shù)之間轉(zhuǎn)換不正確的情況:
-Werror=pointer-to-int-cast -Werror=int-to-pointer-cast -Werror=shorten-64-to-32具有?int?字段(包含指向 C/C++ 對象的指針)的 Java 類也有同樣的問題。在 JNI 源代碼中搜索?jint,并確保切換到?long(Java 端)和?jlong(C++ 端)。
注意:因指針被截斷而引起的崩潰將表現(xiàn)為 SIGSEGV,其中錯誤地址的前 32 位全部為零。
對于 64 位代碼而言,隱式函數(shù)聲明的危險性要高得多。C/C++ 假定隱式聲明的函數(shù)(即編譯器未檢測到聲明的函數(shù))的返回值類型為?int。如果函數(shù)的實(shí)際返回值類型是指針,那么在 32 位系統(tǒng)上是可行的,因為在 32 位系統(tǒng)中指針的類型為?int,但在 64 位系統(tǒng)中,編譯器會丟棄指針的前半部分。例如:
// This function returns a pointer: // extern char* foo();// If you don't include a header that declares it, // when the compiler sees this: char* result = foo();// Instead of compiling that to: result = foo();// It compiles to something equivalent to: result = foo() & 0xffffffff;// Which will then cause a SIGSEGV if you try to dereference `result`.以下編譯器標(biāo)記會將隱式函數(shù)聲明警告變成錯誤,以便您能夠更輕松地查找和解決此問題:
-Werror=implicit-function-declaration如果您有內(nèi)聯(lián)匯編程序,您需要重新編寫該程序或使用普通的 C/C++ 實(shí)現(xiàn)。
如果您對類型大小進(jìn)行了硬編碼(例如,8 或 16 字節(jié)),請使用等效的?sizeof(T)?表達(dá)式(例如?sizeof(void*))來替換它們。
如果需要有條件地編譯不同于 64 位的 32 位代碼,則對于一般性的 32/64 差異,您可以使用?#if defined(__LP64__);對于 Android 支持的具體架構(gòu),可以使用?__arm__、__aarch64__?(arm64)、__i386__?(x86) 和?__x86_64__。
您需要調(diào)整類似?printf?或?scanf?的函數(shù)的格式字符串,因為如果使用傳統(tǒng)的格式說明符,您無法以一種對 32 位和 64 位設(shè)備都正確的方式來指定 64 位類型。您可利用?<inttypes.h>?中的?PRI?和?SCN?宏來解決此問題,PRIxPTR?和?SCNxPTR?分別用于寫入/讀取十六進(jìn)制指針,PRId64?和?SCNd64?分別用于以可移植的方式寫入/讀取 64 位值。
在移位時,您可能需要使用?1ULL?來獲取要移位的 64 位常數(shù),而不能使用僅支持 32 位的?1。
利用 Android App Bundle 減少大小增加量
為您的應(yīng)用添加 64 位架構(gòu)支持可能會導(dǎo)致 APK 的大小增加。我們強(qiáng)烈建議您利用?Android APP Bundle?功能,以盡量減小因在同一 APK 中同時包含 32 位和 64 位原生代碼而對 APK 大小產(chǎn)生的影響。
實(shí)際上,將應(yīng)用改為使用 Android App Bundle 可以縮減 APK 的大小,使其比現(xiàn)在更小。
游戲開發(fā)者
我們知道,遷移第三方游戲引擎是一個耗費(fèi)人力的過程,并且需要很長的準(zhǔn)備時間。慶幸的是,三大最常用的引擎目前都支持 64 位架構(gòu):
- Unreal(自 2015 年起)
- Cocos2d(自 2015 年起)
- Unity(自 2018 年起)
Unity 開發(fā)者
升級到支持的版本
Unity 自版本?2018.2?和?2017.4.16?開始提供 64 位支持。
如果您發(fā)現(xiàn)自己使用的 Unity 版本不支持 64 位架構(gòu),請確定要升級到的版本,并按照 Unity 提供的指南遷移您的環(huán)境,確保將您的應(yīng)用升級到可構(gòu)建 64 位庫的版本。Unity 建議您升級到該編輯器的最新 LTS 版本,以獲取最新的功能和更新。
下面的圖表概述了 Unity 的各個版本以及您應(yīng)該采取的措施:
| 2020.x | ?? | 確保您的構(gòu)建設(shè)置能夠輸出 64 位庫。 |
| 2019.x | ?? | 確保您的構(gòu)建設(shè)置能夠輸出 64 位庫。 |
| 2018.4 (LTS) | ?? | 確保您的構(gòu)建設(shè)置能夠輸出 64 位庫。 |
| 2018.3 | ?? | 確保您的構(gòu)建設(shè)置能夠輸出 64 位庫。 |
| 2018.2 | ?? | 確保您的構(gòu)建設(shè)置能夠輸出 64 位庫。 |
| 2018.1 | ? | 提供實(shí)驗性的 64 位支持。 |
| 2017.4 (LTS) | ?? | 自?2017.4.16?開始支持。 確保您的構(gòu)建設(shè)置能夠輸出 64 位庫。 |
| 2017.3 | ?? | 升級到支持 64 位的版本。 |
| 2017.2 | ?? | 升級到支持 64 位的版本。 |
| 2017.1 | ?? | 升級到支持 64 位的版本。 |
| <=5.6 | ?? | 升級到支持 64 位的版本。 |
更改構(gòu)建設(shè)置以輸出 64 位庫
如果您使用的 Unity 版本支持 64 位的 Android 庫,那么您可以通過調(diào)整構(gòu)建設(shè)置來生成 64 位版本的應(yīng)用。您還需要使用 IL2CPP 后端作為 Scripting Backend(詳見此處)。要為構(gòu)建 64 位架構(gòu)而設(shè)置 Unity 項目,請按以下步驟操作:
點(diǎn)擊?Player Settings。
依次轉(zhuǎn)到?Player Settings Panel > Settings for Android > Other Settings > Configuration
將?Scripting Backend?設(shè)為?IL2CPP。
依次選擇?Target Architecture > ARM64?復(fù)選框。
照常構(gòu)建!
請注意,針對 ARM64 進(jìn)行構(gòu)建需要您專門針對該平臺構(gòu)建您的所有資產(chǎn)。請按照 Unity 的指南來縮減 APK 大小,同時考慮利用?Android App Bundle?功能來減小大小增加量。
合并 APK 和 64 位合規(guī)性
如果您要使用 Google Play 的合并 APK 支持來發(fā)布應(yīng)用,請注意在版本層面評估是否符合 64 位要求。不過,如果 APK 或 app bundle 不會分發(fā)給搭載 Android 9 Pie 或更高版本的設(shè)備,則不適用 64 位要求。
如果您的某個 APK 被標(biāo)記為不合規(guī),但該 APK 比較老舊且無法使其合規(guī),一種策略是在該 APK 清單的?uses-sdk?元素中添加?maxSdkVersion="27"?屬性。這樣一來,此 APK 將不會被分發(fā)給搭載 Android 9 Pie 或更高版本的設(shè)備,因而也就不會再妨礙合規(guī)。
RenderScript 和 64 位合規(guī)性
如果您的應(yīng)用使用 RenderScript 并且是通過較低版本的 Android 工具構(gòu)建的,該應(yīng)用可能會存在 64 位合規(guī)性問題。使用版本低于 21.0.0 的構(gòu)建工具時,編譯器可能會將生成的位碼放到外部?.bc?文件中。64 位架構(gòu)不再支持這些舊的?.bc?文件,因此,如果您的 APK 中有這類文件,就會造成合規(guī)性問題。
要解決此問題,請移除項目中的所有?.bc?文件,將環(huán)境升級到?build-tools-21.0.0?或更高版本,并將 Android Studio 中的?renderscriptTargetApi?設(shè)為 21+,以指示編譯器不要生成?.bc?文件。然后,重新構(gòu)建您的應(yīng)用,檢查是否有?.bc?文件,再將應(yīng)用上傳到 Play 管理中心。
在 64 位硬件上測試應(yīng)用
64 位版本的應(yīng)用應(yīng)提供與 32 位版本相同的質(zhì)量和功能集。請對您的應(yīng)用進(jìn)行測試,以確保使用最新的 64 位設(shè)備的用戶能夠在您的應(yīng)用中獲得優(yōu)質(zhì)的體驗。
要開始測試您的應(yīng)用,您要有支持 64 位架構(gòu)的設(shè)備。時下有很多支持 64 位架構(gòu)的熱門設(shè)備,例如 Google 的 Pixel 以及其他旗艦設(shè)備。
最簡單的 APK 測試方法就是使用 adb 安裝該應(yīng)用。大多數(shù)情況下,您可以提供?--abi?作為參數(shù),用以指示要將哪些庫安裝到設(shè)備上。這樣在設(shè)備上安裝該應(yīng)用時便會僅包含 64 位庫。
:: Command Line # A successful install: > adb install --abi armeabi-v7a YOUR_APK_FILE.apk Success# If your APK does not have the 64-bit libraries: > adb install --abi arm64-v8a YOUR_APK_FILE.apk adb: failed to install YOUR_APK_FILE.apk: Failure [INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=-113]# If your device does not support 64-bit, an emulator, for example: > adb install --abi arm64-v8a YOUR_APK_FILE.apk ABI arm64-v8a not supported on this device安裝成功后,請照常對應(yīng)用進(jìn)行測試,以確保其質(zhì)量與 32 位版本相同。
發(fā)布
如果您覺得應(yīng)用已準(zhǔn)備妥當(dāng),請照常發(fā)布。與往常一樣,請繼續(xù)遵循部署應(yīng)用的最佳做法。我們建議利用封閉式測試軌道向有限數(shù)量的用戶發(fā)布應(yīng)用,以確保應(yīng)用的質(zhì)量一致。
在發(fā)布重大更新時,也務(wù)必要先在支持 64 位的設(shè)備上進(jìn)行全面測試,然后再面向更廣泛的受眾群體發(fā)布。
相關(guān)內(nèi)容
BLOG
Moving Android Studio and Android Emulator to 64-bit versions
With Project Marble, the Android Studio team focused our efforts on making the fundamental features and flows of the Integrated Development Environment (IDE) rock-solid. Performance is an underlying tenant to delivering a high quality IDE. To this
BLOG
Get your apps ready for the 64-bit requirement
Starting August 1, 2019:
/
為所有屏幕開發(fā)游戲
在為 Android 開發(fā)游戲時,重要的是要預(yù)測各種可能的玩家體驗并保持適應(yīng)玩家的實(shí)時交互需求。通過支持不同的玩家體驗,您可以增加游戲的靈活性,幫助您擴(kuò)大游戲的影響范圍。
玩家體驗的具體差異包括以下內(nèi)容:
- 設(shè)備外形:雖然手機(jī)提供了傳統(tǒng)的 Android 設(shè)備體驗,但也可以與其他外形的游戲進(jìn)行交互。Chrome OS 設(shè)備可以運(yùn)行一個 Android 容器來顯示您的游戲??梢赃\(yùn)行 Android 的平板電腦支持多個不同級別的保真度。Android TV 設(shè)備支持細(xì)節(jié)更豐富、更身臨其境的體驗。玩家可以使用顯示擴(kuò)展工具模擬多窗口環(huán)境。在使用可折疊設(shè)備時,玩家可以在游戲過程中更改屏幕大小。
- 交互方式:玩家可以通過觸摸設(shè)備的屏幕來提供輸入,但他們也可以使用鼠標(biāo)、觸摸板、鍵盤或控制器來代替。此外,顯示擴(kuò)展工具和可折疊設(shè)備的可用性允許玩家在更大的屏幕上體驗?zāi)挠螒?#xff0c;從而使更長的游戲會話和更復(fù)雜的界面更加可行。
- 硬件支持:一些基于 Android 的設(shè)備沒有手持設(shè)備中更典型的硬件,例如后置攝像頭、GPS 和網(wǎng)絡(luò)連接。您的游戲應(yīng)該適應(yīng)可用的硬件,并優(yōu)雅地處理某些功能不可用的情況。
本指南介紹了與為不同類型的屏幕和用戶交互開發(fā)游戲相關(guān)的最佳實(shí)踐。本指南還提供有關(guān)設(shè)計游戲和制定有效測試策略的建議。
游戲設(shè)計最佳實(shí)踐
在規(guī)劃游戲的設(shè)計和架構(gòu)時,請遵循以下部分中描述的最佳實(shí)踐。
手動響應(yīng)配置更改
當(dāng) Android 系統(tǒng)檢測到配置變化時,例如屏幕大小、屏幕方向或輸入法的變化,系統(tǒng)默認(rèn)重啟當(dāng)前活動。為了在應(yīng)用程序或游戲中保留狀態(tài),活動默認(rèn)?onSaveInstanceState()?在重新啟動之前和重新啟動?onRestoreInstanceState()?之后調(diào)用。但是,此過程需要活動重新加載所有關(guān)聯(lián)的服務(wù)和資源。要了解有關(guān)此默認(rèn)行為的更多信息,?請參閱處理配置更改指南。
一個典型的游戲會話會經(jīng)歷幾個配置更改。如果您的游戲讓系統(tǒng)處理每個配置更改,您的游戲場景就會被破壞并一遍又一遍地重新啟動,從而降低游戲的性能。因此,我們強(qiáng)烈建議您在游戲中自行處理這些配置更改。
要了解如何將此配置更改邏輯添加到您的游戲中,請參閱有關(guān)如何創(chuàng)建自定義配置更改處理程序的部分。
創(chuàng)建靈活的架構(gòu)
要在盡可能多的設(shè)備上添加對您的游戲的支持,請遵循以下最佳做法:
- 部署 Android App Bundle 而不是單獨(dú)的 APK。?Android App Bundle允許您將不同分辨率和不同架構(gòu)模型(例如 x86、ARM)的工件打包到單個工件中。更好的是,Android App Bundles 支持更高的游戲大小限制;每個基本 APK 可以大到 150 MB,而捆綁包本身可以有很多 GB。
- 添加對 x86 架構(gòu)的支持。此步驟可提高您的游戲在不支持 ARM 的設(shè)備上的性能,因為這些設(shè)備現(xiàn)在可以執(zhí)行指令而無需先翻譯它們。
添加對 Vulkan 的支持
通過支持Vulkan,您的游戲可以獲得更高的圖形性能。大多數(shù)設(shè)備都支持此圖形 API。
創(chuàng)建自定義配置更改處理程序
要聲明游戲自行處理的配置更改類型,請將android:configChanges?屬性添加到<activity>清單中表示屏幕或復(fù)雜界面的每個元素。
以下代碼片段演示了如何聲明您的游戲負(fù)責(zé)屏幕大小、屏幕方向和輸入法更改:
<span style="color:var(--devsite-code-color)"><span style="color:var(--devsite-code-keywords-color)"><activity</span> ...<strong><span style="color:var(--devsite-code-types-color)">android:configChanges</span>=<span style="color:var(--devsite-code-strings-color)">"screenSize|orientation|keyboard|keyboardHidden"</span></strong><span style="color:var(--devsite-code-keywords-color)">></span> <span style="color:var(--devsite-code-keywords-color)"></activity></span> </span>當(dāng)聲明的配置更改發(fā)生時,系統(tǒng)現(xiàn)在調(diào)用不同的方法,?onConfigurationChanged().?在此方法中,添加更新游戲 UI 的邏輯:
- 更新屏幕的比例因子和方向。請記住,出于性能目的,有時最好只在一個維度上縮放游戲的 UI。
- 確定玩家使用的最佳輸入法。
處理屏幕配置更改
只要您在?屬性中分別 包含screenSize和值,您的游戲就會手動處理屏幕大小和屏幕方向的更改。您可以使用這些新值來更新場景的內(nèi)容和玩家輸入?yún)^(qū)域。有關(guān)如何設(shè)計游戲布局以使其更易于更新的指導(dǎo),請參閱支持不同屏幕尺寸的指南。orientationandroid:configChanges
在您的游戲?qū)崿F(xiàn)中onConfigurationChanged(),使用傳入的?Configuration對象和窗口管理器的Display對象分別確定屏幕大小和屏幕方向的更新值。
注意:顯示器的旋轉(zhuǎn)值取決于設(shè)備的默認(rèn)硬件方向。因此,值0表示某些設(shè)備上的縱向和其他設(shè)備上的橫向。
以下代碼片段顯示了如何獲取游戲更新后的屏幕尺寸和方向:
科特林爪哇override fun onConfigurationChanged(newConfig: Configuration) { ? ? super.onConfigurationChanged(newConfig) ? ? val density: Float = resources.displayMetrics.density ? ? val newScreenWidthPixels = (newConfig.screenWidthDp * density).toInt() ? ? val newScreenHeightPixels = (newConfig.screenHeightDp * density).toInt() ? ? // Get general orientation; either Configuration.ORIENTATION_PORTRAIT or ? ? // Configuration.ORIENTATION_LANDSCAPE. ? ? val newScreenOrientation: Int = newConfig.orientation ? ? // Get general rotation; one of: ROTATION_0, ROTATION_90, ROTATION_180, ? ? // or ROTATION_270. ? ? val newScreenRotation: Int = windowManager.defaultDisplay.rotation }
請注意,即使您的應(yīng)用在全屏模式下運(yùn)行,更改可折疊設(shè)備的姿勢也會更改配置。因此,如果用戶在游戲運(yùn)行時折疊或展開設(shè)備,您的應(yīng)用程序可能必須處理屏幕尺寸或像素密度的變化。
特定于游戲的屏幕質(zhì)量
以下部分描述了如何根據(jù)游戲質(zhì)量調(diào)整游戲?qū)ζ聊怀叽缁蚱聊环较蜃兓姆磻?yīng):
全屏模式
在某些平臺上,例如 Chrome OS,Android 應(yīng)用程序和游戲默認(rèn)可以窗口化和調(diào)整大小。如果您的游戲應(yīng)始終以全屏模式運(yùn)行,您可以將?android:resizeableActivity?屬性設(shè)置false為您的<activity>元素之一,如以下代碼片段所示:
<span style="color:var(--devsite-code-color)"><span style="color:var(--devsite-code-keywords-color)"><activity</span> ...<strong><span style="color:var(--devsite-code-types-color)">android:resizeableActivity</span>=<span style="color:var(--devsite-code-strings-color)">"false"</span></strong><span style="color:var(--devsite-code-keywords-color)">></span> <span style="color:var(--devsite-code-keywords-color)"></activity></span> </span>注意:該android:resizeableActivity屬性僅在運(yùn)行 Android 7.0(API 級別 24)或更高版本的設(shè)備上影響您的游戲。
您還可以將android:resizeableActivity屬性設(shè)置為false以防止發(fā)生基于大小的配置更改。但是,除非您的游戲始終以全屏模式運(yùn)行,否則您應(yīng)該將此屬性添加為僅用于測試目的的臨時修復(fù)。
屏幕方向
如果您的游戲依賴于具有特定方向的設(shè)備傳感器,?android:screenOrientation請在游戲的活動中指定一個值,如以下代碼片段所示。此設(shè)置有助于防止游戲中的場景意外顛倒。
<span style="color:var(--devsite-code-color)"><span style="color:var(--devsite-code-keywords-color)"><activity</span> ...<strong><span style="color:var(--devsite-code-types-color)">android:screenOrientation</span>=<span style="color:var(--devsite-code-strings-color)">"landscape"</span></strong><span style="color:var(--devsite-code-keywords-color)">></span> <span style="color:var(--devsite-code-keywords-color)"></activity></span> </span>設(shè)備特定的屏幕質(zhì)量
以下部分描述了如何處理給定某些設(shè)備具有的特定品質(zhì)的基于屏幕的配置更改。
縱橫比
一些設(shè)備支持不同的縱橫比。例如,可折疊設(shè)備設(shè)計為在折疊狀態(tài)下支持 21:9 的縱橫比。要處理這種潛在的縱橫比變化,請至少執(zhí)行以下操作之一:
- 面向 Android 8.0(API 級別 26)或更高版本。
- 使您的游戲場景和界面可調(diào)整大小。在運(yùn)行 Android 7.0(API 級別 24)及更高版本的設(shè)備上設(shè)置?android:resizeableActivity?為。true
-
聲明支持的最大縱橫比。在?<meta-data>與您的游戲關(guān)聯(lián)的屬性中,設(shè)置android.max_aspect為2.4,如以下代碼片段所示。但是請記住,大于您指定的寬高比會導(dǎo)致游戲在顯示器中顯示為?信箱?。
<span style="color:var(--devsite-code-color)"><span style="color:var(--devsite-code-keywords-color)"><application></span> <strong><span style="color:var(--devsite-code-keywords-color)"><meta-data</span> <span style="color:var(--devsite-code-types-color)">android:name</span>=<span style="color:var(--devsite-code-strings-color)">"android.max_aspect"</span><span style="color:var(--devsite-code-types-color)">android:value</span>=<span style="color:var(--devsite-code-strings-color)">"2.4"</span> <span style="color:var(--devsite-code-keywords-color)">/></span></strong> <span style="color:var(--devsite-code-keywords-color)"></application></span> </span>
多個活動同時可見
許多現(xiàn)代設(shè)備支持各種屏幕布局,包括分屏、畫中畫和大顯示區(qū)域。當(dāng)使用其中一種布局時,系統(tǒng)可以同時顯示多個活動。
在運(yùn)行 Android 9(API 級別 28)或更高版本的設(shè)備上,可以同時恢復(fù)所有最重要的可見活動。但是,為了使此行為起作用,您的游戲和設(shè)備的 OEM 都需要選擇啟用該功能。您可以通過在游戲清單中設(shè)置?android.allow_multiple_resumed_activities為來true在游戲中添加支持,如以下代碼段所示:
<span style="color:var(--devsite-code-color)"><span style="color:var(--devsite-code-keywords-color)"><application></span><strong><span style="color:var(--devsite-code-keywords-color)"><meta-data</span> <span style="color:var(--devsite-code-types-color)">android:name</span>=<span style="color:var(--devsite-code-strings-color)">"android.allow_multiple_resumed_activities"</span><span style="color:var(--devsite-code-types-color)">android:value</span>=<span style="color:var(--devsite-code-strings-color)">"true"</span> <span style="color:var(--devsite-code-keywords-color)">/></span></strong> <span style="color:var(--devsite-code-keywords-color)"></application></span> </span>然后,您可以在不同的設(shè)備上測試您的游戲,看看哪些設(shè)備提供了使多重恢復(fù)正常運(yùn)行所需的 OEM 支持。
注意:如果沒有您的游戲和設(shè)備 OEM 的支持,唯一恢復(fù)的活動是最近收到玩家輸入的活動;所有其他可見活動都處于已啟動或已暫停狀態(tài)。
有關(guān)將游戲配置為多窗口顯示的一部分的更多信息,請參閱有關(guān)如何添加多窗口支持的指南。
處理不同類型的交互模型
只要您在屬性中分別 包含keyboard和值,您的游戲就會手動處理鍵盤存在和鍵盤可用性?。您可以使用這些新值來更新游戲的主要輸入法。keyboardHiddenandroid:configChanges
在配置您的游戲以支持多種類型的用戶輸入時,請記住以下幾點(diǎn):
- 檢測輸入法而不是單個設(shè)備。這種心態(tài)可以更輕松地改善玩家體驗,而無需過多關(guān)注玩家可能擁有的特定設(shè)備。
- keyboardHidden在手動處理的配置更改列表中包含該屬性。這樣,您的游戲可以跟蹤鍵盤何時物理連接到設(shè)備但無法使用。
-
確定當(dāng)前可用的輸入法。為此,請?getInputDeviceIds()?在游戲啟動時和每次配置更改后調(diào)用。
您通常可以根據(jù)玩家首選的輸入設(shè)備確定玩家計劃如何與您的游戲互動:
- 玩家通常使用鍵盤或游戲控制器來執(zhí)行快速按鈕序列。
- 玩家通常使用觸摸屏或觸摸板來執(zhí)行更復(fù)雜的手勢。
- 玩家通常使用鼠標(biāo)來執(zhí)行更高精度的輸入。
注意:當(dāng)玩家與您的游戲互動時,輸入法的可用性可能會不穩(wěn)定。例如,他們可能會在玩游戲時斷開鍵盤并插入控制器。
以下部分提供了特定類型輸入設(shè)備的最佳實(shí)踐。
鍵盤
在為您的游戲創(chuàng)建鍵盤布局時,請考慮玩家如何在給定場景中導(dǎo)航以及他們?nèi)绾闻c您的游戲設(shè)置進(jìn)行交互。
WASD 鍵或箭頭鍵通常最適合控制角色移動。最好為可控角色在游戲中可以執(zhí)行的每個重要動作或技能分配一個特定的鍵。為了最大限度地提高玩家體驗,請考慮在游戲中添加對自定義鍵綁定的支持。
玩家還應(yīng)該能夠打開游戲的菜單并使用鍵盤瀏覽它們。Esc關(guān)鍵是用于暫停場景和顯示游戲菜單的通用映射。
注意:即使玩家更頻繁地使用鼠標(biāo)或觸摸板與您的游戲互動,添加鍵盤支持以作為具有輔助功能需求的玩家的替代輸入方法也很重要。
有關(guān)在游戲中支持鍵盤輸入的更多信息,請參閱如何支持鍵盤導(dǎo)航的指南以及如何處理鍵盤操作的指南。
游戲控制器
有關(guān)在游戲中處理控制器輸入的更多信息,請參閱如何支持游戲控制器的指南。
鼠標(biāo)或觸摸板
如果您的游戲支持來自鼠標(biāo)或觸摸板的玩家輸入,請記住玩家與設(shè)備的交互方式與玩游戲不同。請務(wù)必注意,通過請求指針捕獲,所有鼠標(biāo)輸入都指向您的游戲。因此,在您的游戲獲得所需信息后,釋放指針捕獲功能,以便玩家重新獲得對其設(shè)備的標(biāo)準(zhǔn)鼠標(biāo)控制。
在運(yùn)行 Android 8.0(API 級別 26)及更高版本的設(shè)備上,您可以使用鼠標(biāo)捕獲 API 來協(xié)助指針捕獲過程。在對高精度輸入做出反應(yīng)的游戲中,您可以通過調(diào)用getX()和?getY()方法獲取指針的當(dāng)前坐標(biāo)。
有關(guān)在游戲中添加對鼠標(biāo)輸入和觸摸板輸入的支持的更多信息,請參閱有關(guān)如何跟蹤觸摸和指針移動的指南以及有關(guān)如何處理多點(diǎn)觸控手勢的指南。
測試你的游戲
在啟動您的游戲之前,通過完成以下部分中描述的步驟來測試它如何響應(yīng)配置更改。
更新您的測試計劃
驗證游戲功能時,請包括以下測試用例:
- 最小化和最大化包含您的游戲的窗口。(如果您的游戲始終處于全屏模式,則不適用。)
- 更改屏幕大小。
- 更改屏幕方向。(如果您的游戲有固定方向,則不適用。)
- 連接和斷開輸入設(shè)備,例如鍵盤和鼠標(biāo)。
- 如果您的游戲支持,請執(zhí)行多簡歷。
此外,請考慮更新游戲的質(zhì)量控制系統(tǒng),以便您可以針對更廣泛的玩家體驗進(jìn)行優(yōu)化。
有關(guān)測試游戲的最佳實(shí)踐,請參閱測試基礎(chǔ)指南。
使用測試和調(diào)試工具
您可以使用平臺支持的各種工具執(zhí)行測試:
-
模擬器,包括Android 模擬器和?Firebase 測試實(shí)驗室。
注意:Android 模擬器包括對Chrome OS和?可折疊設(shè)備的支持。
-
系統(tǒng)跟蹤。
-
Chrome OS Performance Analyzer,在運(yùn)行 Chrome OS M75 或更高版本時可用。
游戲模式
游戲模式 API和?游戲模式干預(yù)允許您通過根據(jù)用戶設(shè)置或游戲特定配置優(yōu)先考慮特性(例如性能或電池壽命)來優(yōu)化游戲玩法。
從Android 12開始,游戲模式 API 和干預(yù)措施可?在選定設(shè)備上使用。
使用游戲模式 API 進(jìn)行優(yōu)化
您可以使用Game Mode API來識別用戶選擇的當(dāng)前游戲模式,然后根據(jù)他們的選擇優(yōu)化您的游戲以獲得最佳性能或電池壽命。
了解如何設(shè)置、優(yōu)化和發(fā)布您的游戲以支持標(biāo)準(zhǔn)、性能和電池模式。
游戲模式干預(yù)
游戲模式干預(yù)是原始設(shè)備制造商 (OEM) 設(shè)置的游戲特定優(yōu)化,旨在提高開發(fā)人員不再更新的游戲的性能。
了解如何使用性能和電池模式為您的游戲設(shè)置、測試和提交干預(yù)措施。
重要提示:每個游戲都可以實(shí)現(xiàn)游戲模式 API 行為,向 OEM 建議游戲模式干預(yù)設(shè)置,或明確選擇退出游戲模式干預(yù)。
警告:OEM 可以選擇在沒有開發(fā)人員反饋的情況下實(shí)施游戲模式干預(yù)。
游戲模式 API
當(dāng)用戶選擇相應(yīng)的游戲模式時,游戲模式 API 允許您優(yōu)化游戲以獲得最佳性能或最長的電池壽命。
或者,您可以提交?游戲模式干預(yù)請求,以提高開發(fā)人員不再更新的游戲的性能。
游戲模式 API 和干預(yù)可在部分?Android 12設(shè)備上使用。
重要提示:每個游戲都可以實(shí)現(xiàn)游戲模式 API 行為,向 OEM 建議游戲模式干預(yù)設(shè)置,或明確選擇退出游戲模式干預(yù)。
警告:OEM 可以選擇在沒有開發(fā)人員反饋的情況下實(shí)施游戲模式干預(yù)。
設(shè)置
要在游戲中使用 Game Mode API,請執(zhí)行以下操作:
下載并安裝?Android 12 Preview SDK。
在AndroidManifest.xml文件中,通過設(shè)置元素appCategory中的屬性將?您的應(yīng)用聲明為游戲 :<application>
// Only call this for Android 12 devices if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ) { ? // Get GameManager from SystemService ? GameManager gameManager = Context.getSystemService(GameManager.class); ? // Returns the selected GameMode ? int gameMode = gameManager.getGameMode(); }
| 不支持 | 游戲未聲明對游戲模式 API 的支持,也不支持游戲模式干預(yù)。 |
| 標(biāo)準(zhǔn) | 用戶沒有選擇游戲模式或用戶選擇了標(biāo)準(zhǔn)模式。 |
| 表現(xiàn) | 提供最低的延遲幀速率,以換取電池壽命和保真度的降低。 |
| 電池 | 提供盡可能長的電池壽命,以換取降低的保真度或幀速率。 |
重要提示:省電模式是特定于游戲的,不會影響系統(tǒng)級 Android 省電模式的行為。
在onResume函數(shù)中添加查詢游戲模式狀態(tài)的代碼 :
?重要提示:在恢復(fù)暫停的進(jìn)程時,您的應(yīng)用程序必須始終查詢 getGameMode() 方法。有關(guān)詳細(xì)信息,請參見上圖。
最佳實(shí)踐
如果您的游戲已經(jīng)支持多個保真度和幀速率目標(biāo),您應(yīng)該確定性能和節(jié)電模式的適當(dāng)設(shè)置:
-
要始終如一地實(shí)現(xiàn)最大設(shè)備幀速率:考慮稍微降低保真度以實(shí)現(xiàn)更高的幀速率。
-
要延長電池壽命:考慮選擇較低的顯示刷新率(例如 30Hz 或 60Hz)并使用幀步調(diào)來瞄準(zhǔn)降低的刷新率。
對于第一人稱射擊游戲、多人在線戰(zhàn)斗競技場 (MOBA) 和角色扮演游戲 (RPG) 等高保真游戲,您應(yīng)該專注于實(shí)現(xiàn)高一致的幀速率,以最大限度地提高用戶沉浸感。
對于高保真游戲和休閑游戲,您應(yīng)該支持省電模式,以通過降低峰值幀速率來延長游戲時間。
測試
通過?adb設(shè)置游戲模式狀態(tài)來嘗試新的游戲行為:
adb shell cmd game mode [standard|performance|battery] <PACKAGE_NAME>出版
要啟用游戲模式 UI,請將以下內(nèi)容添加到?<application>AndroidManifest.xml 文件中的元素。
<span style="color:var(--devsite-code-color)"><code><span style="color:var(--devsite-code-keywords-color)"><application></span><span style="color:var(--devsite-code-comments-color)"><!-- default is false --></span><span style="color:var(--devsite-code-keywords-color)"><meta-data</span><span style="color:var(--devsite-code-types-color)">android:name</span>=<span style="color:var(--devsite-code-strings-color)">"com.android.app.gamemode.performance.enabled"</span><span style="color:var(--devsite-code-types-color)">android:value</span>=<span style="color:var(--devsite-code-strings-color)">"true"</span><span style="color:var(--devsite-code-keywords-color)">/></span><span style="color:var(--devsite-code-comments-color)"><!-- default is false --></span><span style="color:var(--devsite-code-keywords-color)"><meta-data</span><span style="color:var(--devsite-code-types-color)">android:name</span>=<span style="color:var(--devsite-code-strings-color)">"com.android.app.gamemode.battery.enabled"</span><span style="color:var(--devsite-code-types-color)">android:value</span>=<span style="color:var(--devsite-code-strings-color)">"true"</span><span style="color:var(--devsite-code-keywords-color)">/></span>... <span style="color:var(--devsite-code-keywords-color)"></application></span> </code></span>重要提示:游戲模式 UI 僅適用于部分 Android 12 設(shè)備,不適用于 Android 12 Beta 版本。
下一個
當(dāng)無法提供游戲更新時,請閱讀游戲模式干預(yù)以提高游戲性能。
//
游戲模式干預(yù)
游戲模式干預(yù)是原始設(shè)備制造商 (OEM) 設(shè)置的游戲特定優(yōu)化,旨在提高開發(fā)人員不再更新的游戲的性能。例如:
- WindowManager 后備緩沖區(qū)調(diào)整大小。
- 使用 ANGLE 而不是本機(jī) GLES 驅(qū)動程序。
或者,如果可以更新游戲,您可以使用?Game Mode API優(yōu)化性能和電池。
游戲模式 API 和干預(yù)可在部分?Android 12設(shè)備上使用。
重要提示:每個游戲都可以實(shí)現(xiàn)游戲模式 API 行為,向 OEM 建議游戲模式干預(yù)設(shè)置,或明確選擇退出游戲模式干預(yù)。
警告:OEM 可以選擇在沒有開發(fā)人員反饋的情況下實(shí)施游戲模式干預(yù)。
WindowManager 后臺緩沖區(qū)調(diào)整大小
WindowManager?backbuffer?resize 干預(yù)可以減少設(shè)備的 GPU 負(fù)載。當(dāng)游戲以目標(biāo)幀速率進(jìn)行時,它還可以減少電池消耗。
啟用調(diào)整大小后,最多可降低 30% 的 GPU 功率和 10% 的系統(tǒng)功率。結(jié)果可能會因使用的設(shè)備、環(huán)境條件和其他因素(例如同時處理)而異。
受 GPU 限制的無節(jié)奏游戲可能會在減少 GPU 負(fù)載期間體驗更高的幀速率。但是,我們強(qiáng)烈建議所有游戲都保持?良好的節(jié)奏,因為不均勻的幀速率會顯著影響用戶對性能的看法。
評估
要自行評估 WindowManager 后緩沖調(diào)整大小干預(yù),請使用以下adb命令。90% 的調(diào)整大小幾乎可以忽略不計,而 50% 則意義重大。
adb shell cmd game downscale [0.5|0.6|0.7|0.8|0.9|disable] <PACKAGE_NAME>警告:在 Android 12 中,子進(jìn)程的大小可能無法正確調(diào)整。應(yīng)特別注意查看 toast/彈出窗口的 UI?;蛘?#xff0c;我們建議您將調(diào)整大小設(shè)置限制為 70%。
設(shè)置模式
您應(yīng)該驗證對性能和電池模式的干預(yù),如下所述。
| 表現(xiàn) | 提供最低的延遲幀速率,以換取電池壽命和保真度的降低。 |
| 電池 | 提供盡可能長的電池壽命,以換取降低的保真度或幀速率。 |
要驗證每種模式的干預(yù), 請在AndroidManifest.xml文件中的<application>元素 下啟用這些模式。
-
啟用性能模式:
<span style="color:var(--devsite-code-color)"><code><span style="color:var(--devsite-code-comments-color)"><!-- default is false --></span> <span style="color:var(--devsite-code-keywords-color)"><meta-data</span><span style="color:var(--devsite-code-types-color)">android:name</span>=<span style="color:var(--devsite-code-strings-color)">"com.android.app.gamemode.performance.enabled"</span><span style="color:var(--devsite-code-types-color)">android:value</span>=<span style="color:var(--devsite-code-strings-color)">"true"</span><span style="color:var(--devsite-code-keywords-color)">/></span> </code></span> -
啟用電池模式:
<span style="color:var(--devsite-code-color)"><code><span style="color:var(--devsite-code-comments-color)"><!-- default is false --></span> <span style="color:var(--devsite-code-keywords-color)"><meta-data</span><span style="color:var(--devsite-code-types-color)">android:name</span>=<span style="color:var(--devsite-code-strings-color)">"com.android.app.gamemode.battery.enabled"</span><span style="color:var(--devsite-code-types-color)">android:value</span>=<span style="color:var(--devsite-code-strings-color)">"true"</span><span style="color:var(--devsite-code-keywords-color)">/></span> </code></span>
測試你的游戲
分配不同的調(diào)整大小值以查看您的游戲如何受到 WindowManager 后備緩沖區(qū)調(diào)整大小干預(yù)的影響:
adb shell device_config put game_overlay <PACKAGE_NAME> mode=2,downscaleFactor=0.7:mode=3,downscaleFactor=0.8重要提示:在上面的示例中,mode=2是“性能”并且mode=3?是“省電模式”。該downscaleFactor值指定為適用于調(diào)整大小設(shè)置的百分比(0.7 為 70%,0.8 為 80%)。
向 OEM 提交干預(yù)措施
對于 Android 12,每次干預(yù)都必須由設(shè)備 OEM 設(shè)置。?對于 Pixel 設(shè)備,請?zhí)峤荒恼埱蟛⑻峁┮韵滦畔?#xff1a;
游戲包名。
設(shè)備和型號詳細(xì)信息。
請求模式的干預(yù)值。
退出干預(yù)
或者,您可以通過選擇退出來控制是否對您的游戲應(yīng)用干預(yù)。每個干預(yù)都有自己的退出設(shè)置。
要禁用 WindowManager 后緩沖調(diào)整大小干預(yù),請將以下內(nèi)容添加到<application>?AndroidManifest.xml 文件中的元素。
<span style="color:var(--devsite-code-color)"><code><span style="color:var(--devsite-code-keywords-color)"><meta-data</span><span style="color:var(--devsite-code-types-color)">android:name</span>=<span style="color:var(--devsite-code-strings-color)">"com.android.graphics.intervention.wm.allowDownscale"</span><span style="color:var(--devsite-code-types-color)">android:value</span>=<span style="color:var(--devsite-code-strings-color)">"false"</span><span style="color:var(--devsite-code-keywords-color)">/></span> </code></span>重建并重新提交您的游戲以選擇退出。
重要提示:默認(rèn)情況下,原始設(shè)備制造商 (OEM) 可以設(shè)置干預(yù),除非您明確選擇退出游戲。
資源
有關(guān)測量和優(yōu)化游戲性能的更多信息:
-
System Profilers?- 分析 CPU 使用率和圖形調(diào)用。
-
Android GPU Inspector?- Android 上的配置文件圖形。
-
Android Frame Pacing Library?- 幫助 OpenGL 和 Vulkan 游戲?qū)崿F(xiàn)流暢的渲染和正確的幀節(jié)奏。
-
Android Performance Tuner?- 大規(guī)模測量和優(yōu)化 Android 設(shè)備的幀速率和圖形。
-
Energy Profiler?- 查找您的應(yīng)用在哪些地方使用了不必要的能源。
//
///
總結(jié)
以上是生活随笔為你收集整理的Unity app提高设备可用性的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 科目三考试经验与技巧——长春长德科目三考
- 下一篇: php对接linepay支付