實戰 Android OBB on Cocos2d-x

Terry Huang
安郡尼爾筆記
Published in
7 min readMay 22, 2018

關於 Android OBB 擴充程式檔(APK Expansion Files)的介紹,可參考前一篇文章:開始使用 Android OBB 擴充程式檔(APK Expansion Files)

以下將會介紹,在實作上如何將 Cocos2d-x 導入 Android OBB 的封裝與使用。主要的流程是,在 App 中建立一個初始介面,用來確認與處理程式擴充檔程式檔尚未準備好的狀況,並與原本的資源檔分離封裝,縮小主程式所需的容量;另外的任務,則是龐大資源檔的封裝、測試與優化。

建立溝通的橋樑

在整個確認擴充程式檔的過程中,一定有相當多的權限、命令需要互通,所以我們先準備一個 JNI Bridge 來實作可能會用到的方法,初略包含以下:

  • hasReadExternalPermission -> boolean,取得是否擁有外部讀取權限
  • hasResource -> boolean,取得是否擁有資源檔
  • requestReadExternalPermission,請求外部讀取權限
  • requestPermissionResult(boolean is_granted),回傳請求權限的結果

Android Java 端可以參考這個 Snippets

p.s. 當您想要實作更多功能(比如:下載器)時,便會需要更多邏輯互動,可依照需求進行擴充

準備一張遮羞布,和資源檔分手

在整個確認擴充程式檔的過程中,通常需要額外的等待過程,比如:求取權限、下載擴充檔…等等,將會需要一個靜態的介面用來過場。因此,準備一個 Loading Scene,並額外的把這個 Scene 所需要的資源,存到另一個資源資料夾(比如:LoadingResources),與原本的資源資料夾分開。

呆呆童書的 Loading Scene,示意圖非此方法實作

接著修改 AppDelegate 中 applicationDidFinishLaunching 將無法卻認外部程式檔的情況,都導向 Loading Scene 進行處理

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)if (SystemHelper::HasPermissionRead()
&& SystemHelper::HasResource()) {
// 程式擴充檔確認,前進 Start Scene
} else {
// 無法確認,前進 Loading Scene
}
#else// 其他平台,前進 Start Scene#endif

另外修改 build.gradle,更改 assets.srcDir

sourceSets.main {
java.srcDir "src"
res.srcDir "res"
manifest.srcFile "AndroidManifest.xml"
assets.srcDir "../../LoadingResources"
}

此時,Android 的封裝,應該就是不涵蓋原本資源檔的小包裝。並且經過判斷,會因為無擴充檔案而導向 Loading Scene。

準備需要的一切

在 Loading Scene 中,我們必須確保整個權限與資源檔的狀態,並進行應對,以最簡易版的起手式來看,至少得完成兩樣程序:

  1. 確認 ReadExternalStorage 權限,如果還沒擁有,則發起權限請求。當使用者同意則往下一步;不同意則以訊息告知無法繼續。
  2. 確認 OBB 檔案存在,如果存在,則進入正常 Start Scene;如不存在,則以訊息告知檔案不完全,請刪除並到 Play Store 重新下載。

注意,上述為最精簡版的處理流程。完整的上線產品,需要更詳細、流暢的處理過程,請參閱前一文中:完整的起手式。

打包被分手的資源檔

研究現有 cocos2d-x 的程式碼,便可發現資源的取用邏輯是:如果外部 OBB 存在,則使用外部的程式擴充檔;如不存在,則使用 APK 封裝中的資源。因此只要將資源檔放置在正確的位置,使用正確的命名,並取得授權,主程式便可以正常執行。

以目前 cocos2dxhelper.java 中的實作 (Version 3.16) 來看,目前的程式擴充檔支援有以下的限制:

  1. 僅支援 main obb,不支援 patch obb
  2. 完全與 APP versionCode 綁定,如果選則沿用擴充檔會無法找到
  3. 以 getAPKExpansionZipFile 來取得資源

當然,以上的限制都可以手動的改寫來進行更多的支援。我們先以目前的設定來嘗試封裝一個可用的程式擴充檔,透過以下指令:

  • 移到 Resource 資料夾
cd /Path/To/Project/Resources
  • 將資料夾中的一切進行封裝,其中針對 ogg, mp3, wav 等檔案採用不壓縮封裝,這樣能讓資料直接被取用,而不用先解壓縮出來
zip -rn .ogg:.mp3:.wav ../main.1.com.test.app.obb ./

p.s. 其中 1 為擴充程式檔版本,對應 versionCode。com.test.app 為程式 applicationId。

  • (選用)接下來便可以順便簡單地將這個檔案送進手機中進行測試
adb push ../main.1.com.test.app.obb /storage/emulated/0/Android/obb/com.test.app

p.s. 您必須先安裝主程式 App,並使用檔案瀏覽器建立 /Android/obb/com.test.app 資料夾

  • 此時開啟 App 並給予授權,應該就能與未拆分的 App 一樣的使用。而此程式擴充檔,便可以與 APK 一起提交到 Play Store 中上架。

原來是優化的部分啊

在目前 cocos2dxhelper.java 中的實作,最可惜的便是限制 expansion version 需要完全與 APP versionCode 綁定,這會大幅度的提高更新的負擔。因此我們透過簡單的改寫優化,讓 helper 能讀取不同版號的擴充程式檔。

改寫 getObbFile() 的方法,透過列出符合檔案清單,來取出目前的 expansion version,取代程式版本的 versionCode,這樣便可讓 APKExpansionSupport 取得正確的檔案

String pathToOBB = sActivity.getObbDir().toString(); String[] fileNames = new File(pathToOBB).list(new FilenameFilter() {                    
public boolean accept(File dir, String name) {
return name.startsWith("main.") && name.endsWith(".obb");
}
});
if (fileNames.length > 0) {
versionCode = Integer.parseInt(fileNames[0].split("\\.")[1]); }

詳細請參閱:此文件

超級好康,限時免費,歡迎下載 ~

《呆呆童書 — 我的家》衝到兒童榜第一名了!
感謝大家一起來支持台灣本土的原創內容

《呆呆童書 — 我的家》限時免費中!
慶祝雙平台上架,5/21~5/25 限時免費(原價90元),
之後還有更多故事會陸續更新,
快把好消息分享給親朋好友吧!

iOS 版本:https://bit.ly/DaiHomeA
Android 版本:https://bit.ly/DaiHomeG

--

--

Terry Huang
安郡尼爾筆記

Co-Founder of LiRise Co.,Ltd. In charge of innovative affairs development. Tags: Guitar, Golf, Photograph, Cocktail, Dance, Diving, Travel.