close

外部資源檔,AndroidQT如何做?

 

啟稿: 2015/01/01

完稿: 2015/01/10

 

QT CueTai線索台

跨平台實作06-跨平台實作進階:採用外部資源檔,Android下之實例

 

Android平台作業系統目錄結構究竟會像Windows, Mac OS還是iOS呢?基本上Android是延伸於Linux作業系統而來的,所以與Mac OSiOS較像而與Windows差異較大,現在來看Android作業系統的範例。

 

l   Androidapk封裝結構

各位可以找到原來我們在"跨平台實作01"Android所建置的安裝程式來研究看看;以我的例子建置的程式放在以下的目錄;

          E:\QtWork\build-analogclock-Android_for_armeabi_GCC_4_8_Qt_5_3_0-Release\android-build\bin

 06-01  

 

其實Android建置所產生的QtApp-debug.apk是壓縮檔,你可以先將此檔複製一份備份,再將副檔名apk改為zip,利用WinzipWinRar就可以看到整體安裝封裝的結構如下:

 06-02

在此結構中有assetslibsMETAINFres四個目錄,與QT自動產生的android-build目錄結構相似,各位可在QtApp-debug.apk所在目錄往上一層,如我電腦放在以下目錄:

 06-03

 

所以回過頭來看QtApp-debug.apk內之目錄結構,res/目錄就是放置資源檔的地方;但封裝後的執行檔在哪裡呢?各位若有聽過deApk反譯器,就會知道classes.dex就是Java編譯的binary code執行程式!

 

查看這樣的結構,似乎與Eclipse建構Android專案的結構有些不同;以下是一個Android專案的範例,在範例中可以看到Android專案會規畫一個res/的目錄來擺所有資源檔,因為應用程式會在手機、平板等各種解析度下執行,所以有drawabledrawable-hdpidrawable-ldpidrawable-mdpi等次目錄來放不同解析度的畫面資源,如下圖:

 06-04

 

但是QtApp-debug.apk封裝內之目錄結構,res/目錄下只有一個layout次目錄,看起來QT default建置Android Project交由Eclipse封裝後之目錄結構不足;接下來我們就需要在QT做些手法!

 

l   QT下建置Android安裝結構

目前看來AndroidiOS 封裝後結構類似,因此我們希望可以做到類似Android Project一般將所有需要的資源檔放在封裝後的根目錄下的一個res/目錄來放置。

根據之前的經驗,有關這方面的訊息可以在QT說明畫面的搜尋欄位輸入keyword " QT for Android deployment",得到的說明;輸入後,前兩個說明與我們現在需求比較相關,一是"Deploying an Application on Android",另外是" Deploying Applications to Android Devices";首先先看" Deploying Applications to Android Devices"如下:

 06-05

其內容主要是在說明有關如何設定Deploy configurations如下,但這不是我們要的重點,所以我們就用最保守但是size最大的Bundle QT Libraries in APK!

 06-06

 

接下來來看"Deploying an Application on Android"如下,這是一篇相當豐富而有用的資料:

 06-07  

在這篇一開始”The APK package”就提到我們剛才所說過的Android建置所產生的.apkZIP壓縮檔,接下來的章節”Package template”就提到QT自動建置出來的主要的三大部份:AndroidManifest.xmlJava coderes/ folder下的resource;對我們來說,我們的目的就是要加我們所需要的檔案到res/ 目錄下,似乎應該參考resource這一章節,但仔細拜讀後會發現,內容又似乎與我們想要的不同,主要在介紹QT自動加入libs.xmlstrings.xml的功用,以後有機會研究QT如何讓android動起來再來參考此巨著還來的及!

雖然在此篇也找不到所需資料,但是在提到qmake自動建置中以提到以下命令:

      make install INSTALL_ROOT=$BUILD_TARGET

這個線索與我們在前篇為了Windows作業平台所查過的資料有關,在QT說明中搜尋過"Qmake INSTALLS"顯示巨集INSTALLS的用法:

 

 06-08

照原文Specifies a list of resources that will be installed when make install or a similar installation procedure is executed 的意思,就是在安裝或類似的過程中將所列的資源檔一起安裝,而且我們查到此功能似乎是針對Unix作業平台設計的,如下圖所示:

 06-09

在此篇一開始就提到Android作業系統其實也就是Linux作業系統演化過來的,所以特性是一樣的;另外在網路Google也會得到相關的資訊,所以可以知道,對於Android作業系統要將所有需要的資源檔放在封裝後的根目錄下的一個res/目錄來放置就該用巨集命令INSTALLS,所以接下來我們就可以修改pro的巨集方法如下:

ResourcesFiles.files=\

        ../analogclock/audio/alarm.wav\

        ../analogclock/audio/bird.wav\

        ../analogclock/audio/cricketnight.wav\

        ../analogclock/audio/dolphin.wav\

        ../analogclock/audio/hour.wav\

        ../analogclock/audio/laser.wav\

        ../analogclock/audio/water.wav

 

    ResourcesFiles.path=/res
    INSTALLS+=ResourcesFiles

 

我們先不管程式如何修改,先看建置的結果,你會發現得到以下的錯誤:

[echo] Handling Resources...

[aapt] Generating resource IDs...

[aapt] invalid resource directory name: E:\QtWork\build-analogclock-Android_for_armeabi_GCC_4_8_Qt_5_3_0-Debug\android-build\res/alarm.wav

[aapt] invalid resource directory name:

:

[aapt] invalid resource directory name: E:\QtWork\build-analogclock-Android_for_armeabi_GCC_4_8_Qt_5_3_0-Debug\android-build\res/water.wav

09:49:06: 行程 "C:\Qt\Qt5.3.0\5.3\android_armv5\bin\androiddeployqt.exe" 已離開。離開代碼 16 。

Error while building/deploying project analogclock (kit: Android for armeabi (GCC 4.8, Qt 5.3.0))

執行步驟 'Deploy to Android device' 時

 

看起來/res對於androiddeployqt.exe來說認為是不合法的目錄,這相當打擊我們的信心,為什麼在QT說明與網路都提到的方法不能用呢?再次到網路Google有關的資訊,在一堆的網文中有很多用ANT來進行post process,不過研究ANT相當費工夫還不易達到效果;但是會發現過去有人問過相關的問題” How to add qt resources to android APK file?”,文中有簡單提到” You'll need to add the images to yourassetsfolder”,再去查看Android有關assets目錄的定義與用法,可以發現assets本意就是讓使用者儲存任意二進位檔案,該assets目錄與res/raw目錄類似,而且比res/raw目錄更勝的assets目錄中可以建立任意階層的子目錄。

 

所以我們就可以重新修改pro的巨集方法如下:

ResourcesFiles.files=\

        ../analogclock/audio/alarm.wav\

        ../analogclock/audio/bird.wav\

        ../analogclock/audio/cricketnight.wav\

        ../analogclock/audio/dolphin.wav\

        ../analogclock/audio/hour.wav\

        ../analogclock/audio/laser.wav\

        ../analogclock/audio/water.wav

 

    ResourcesFiles.path=/assets
    INSTALLS+=ResourcesFiles

 

先看建置的結果,你會發現建置到執行都沒有錯誤了,仔細檢查建置過程可看到如下訊息:

copy /y E:\QtWork\analogclock\Configure.txt E:\QtWork\build-analogclock-Android_for_armeabi_GCC_4_8_Qt_5_3_0-Debug\android-build\assets

複製了 1 個檔案。

:

copy /y E:\QtWork\analogclock\audio\water.wav E:\QtWork\build-analogclock-Android_for_armeabi_GCC_4_8_Qt_5_3_0-Debug\android-build\assets

複製了 1 個檔案。

copy /y "libanalogclock.so" "E:\QtWork\build-analogclock-Android_for_armeabi_GCC_4_8_Qt_5_3_0-Debug\android-build\libs\armeabi\libanalogclock.so"

複製了 1 個檔案。

 

看起來這樣的巨集是對的,現在我們可以開始修改程式了!

 

l   修改程式

雖然QTWindows/Mac OS作業系統開發平台上,建置時產生的目錄位置在debugrelease是完全不同的兩個目錄,但真正放進Android device時用戶安裝的目錄都放在data/app下,因此我們就不必分辨操作模式是debug還是release模式。

為了程式的一致性,我們還是必須在原始碼中決定程式所在路徑目錄S_CurrentPath、絕對路徑目錄S_AbsPath及資源檔相對路徑目錄S_ResPath三變數,所以程式一開始改成如下:

        clock.S_CurrentPath=clock.D_Current.path()+"/";
        clock.S_OpPath="";
        clock.S_ResPath="assets:/";
           clock.S_AbsPath=clock.S_CurrentPath+clock.S_OpPath;
           QDir::setCurrent(clock.S_AbsPath);

 

程式中取用資源檔的時候就如同當初在Windows/Mac OS寫法相似,只有目錄名稱不同,在此應該為下列命令方式取用:

    soundQuarter=newQSound("assets/alarm.wav");

 

因為在程式前頭就已經記錄資源檔相對路徑目錄S_ResPath,所以在原始碼中就完全不用改,與之前的用法一樣!如下用法:

        soundQuarter=newQSound(S_ResPath+"alarm.wav");

 

l   建置與執行

現在大功告成了,如同我們前面所說的,在Android作業平台下可以不用在意debug/release狀態,所以可以不用管clock.OpNow內容;建置執行後同樣的去檢查所產生的QtApp-debug.apk壓縮檔,內容如下:

 06-10

太好了,所有的資源檔都拷貝到assets/目錄下了!!!

 

l  延伸應用及問題

雖然我們已經學會因應四種不同的作業系統平台如何加入個別的資源檔,但是每次當我們要編譯不同的作業系統就要進行不同pro設定與source code的更動,實在不方便;因此問題來了,是否QT可以修改程式可以自動判斷所在的作業系統平台而自行設定與更動呢?

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 Philip4G 的頭像
    Philip4G

    Philip4G四眼仙機的部落格

    Philip4G 發表在 痞客邦 留言(1) 人氣()