2015年2月10日 星期二

(Android API Guides系列)Android 應用程式架構基礎(下)

  大家好,睽違了2天相信大家都很期待下集,那就讓我們繼續看完關於Google釋出的API解說中最基本但也最重要的部分:Application Fundamentals吧!
  
  在本集中我們將會看到定義程式內容和性質的Manifest files(清單檔)和存放各種App會使用的資源的Resource(資源檔)檔案。

Manifest files(清單檔)


  在Android系統啟動一個APP組件之前,它必須先到這個通常在專案中名為AndroidManifest.xml的檔案去檢查該組件是否存在之後才能啟動。所以我們必須在這個xml檔案(我們可以在Android Studio的專案中關於Manifest的資料夾中找到它)中宣告所有的成員。

  除了宣告組件存在之外,manifest檔還有以下主要功能:
  • 識別該APP需要的使用者權限,例如網際網路存取、讀取通訊錄等
  • 宣告最小相容的API等級(minimum API Level,也就是用來組成、編譯你的程式的API版本,越新通常會包含越多功能,1.0.2版預設為8)
  • 宣告會用到的軟硬體成員,例如相機、藍芽裝置、多點觸控螢幕。
  • 外部API函式庫(那些不包含在Android framework APIs裡面的,例如Google Maps library)

1.宣告組件


如上所述,宣告組件成員是manifest檔案主要任務,方法可以如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:icon="@drawable/app_icon.png" ... >
        <activity android:name="com.example.project.ExampleActivity"
                  android:label="@string/example_label" ... >
        </activity>
        ...
    </application>
</manifest>
<application>標籤裡,android:icon指向某個決定APP圖示的.png Resource檔。在<activity>標籤裡,android:name定義了開啟的activity的類別名稱(ExampleActivity)。android:label則定義了此activity的顯示名稱。

  Activities, services, content providers這些組件,如前述地,在我們的Java程式碼中寫完完整功能之後,我們還必須在manifest中宣告之後才能被系統"看到",否則無法運作。但是,Broadcast receivers是個例外,它可以像他們另外三個夥伴一樣在manifest檔中宣告,也可以動態地在Java程式碼裡空降(就像BroadcastReceiver一樣)並驕矜地呼叫registerReceiver()來完成系統註冊(讓系統知道它存在)這個trivial的動作。

想知道更多有關如何為你的APP組成一個manifest清單檔請看The AndroidManifest.xml File

2.宣告組件功能


如前所述,在談到活化組件時,我們提到可以用Intent來開啟三種組件(activities, services, and broadcast receivers)。方法上我們可以直接言明目標組件是誰,在Intent中直接指向它。然而Intent強大的地方就是在其隱匿性(Implicit),怎麼說呢?隱匿性只需要我們描述動作類型(或是也可以進一步告訴Intent這個信使我們想要操作的資料),這樣系統就能夠幫我們找到一個裝置中的組件(可以是別的APP的成員)來幫我們完成這個動作。如果有複數的組件能執行Intent所描述的動作,使用者也可以自行選擇要使用哪個組件。(編按:聽起來真的很強大啊XD)

  至於系統要怎麼識別出那些組件能達成Intent的任務呢?原來就是manifest裡面的宣告組件功能的區塊啊!當我們在APP的清單檔中宣告了一個activity,我們可以選擇性地把宣告"這個activity具有甚麼功能"的Intent filter給函括進去,這樣一來從其他APP來的Intent就可以取用我這個activity的功能了!<intent-filter>的用法如下:

<manifest ... >
    ...
    <application ... >
        <activity android:name="com.example.project.ComposeEmailActivity">
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <data android:type="*/*" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>
  注意到<action android:name="android.intent.action.SEND" />這行定義了要捕捉的動作名稱"SEND",下一行定義了檔案類型,再下一行則是Intent的類型(其實這邊我不懂"*/*",知道的人可以教我XD)。如此一來,如果從另一個APP傳出了含有ACTION_SEND動作(編寫並寄送郵件)的intent,系統可能會開啟我們寫的activity來讓使用者有另外一種選項編寫並寄送郵件。
想知道更多有關如何建立intent filter的人可以參考Intents and Intent Filters document。

3.宣告APP之系統需求


  簡單來說就是為了在上架到Google Play商店時能夠讓使用者快速知道你的APP與其裝置之相容性,我們必須把相關資訊放在manifest檔案裏頭。舉例來說,如果你的APP需要用到相機且必須要在Android 2.1(API Level 7)以上運行,你可以這樣做:
<manifest ... >
    <uses-feature android:name="android.hardware.camera.any"
                  android:required="true" />
    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="19" />
    ...</manifest>
這樣一來,沒有相機(沒有才怪)或是Android系統舊於2.1版的可憐孩兒們就不能從Google Play安裝你的APP了(哭哭)。不過為了吸收最大利益廣大市民福祉,你也可以android:required屬性改為false,這樣一來系統會在執行時檢查裝置是否有相機,你也可以用此方式disable掉一部分需要用到相機的功能,使APP能正常運作。

  關於裝置相容性,等不及的人可以看Device Compatibility document。


App Resources(APP資源檔)

一個完整的APP是由Java程式碼和我們會用到的資源(例如圖像、音訊、以及其他關於視覺設計的部分)組成。而這些資源都會被定義在XML格式的資源檔中(Android Studio專案中的res資料夾裡面),舉例來說,你可以在xml資源檔中定義你設計的activity中存在的動畫(animation)、選單(menu)、造型(style,color)、佈局(layout)。因為這些資源與程式碼被分開來管理,所以在更新以上部分的內容時,不需要再更改程式碼,這使得你的APP在適應不同裝置時(例如不同語言、不同螢幕大小的手機)能更快達到最佳化。

  至於要怎麼做到最佳化呢?我們需要一點前情提要:
SDK build tool(軟體開發建置工具)會為每一個APP專案用到的資源定義一個唯一的整數ID,以用來當作Java程式碼及其他xml資源檔參考(reference)此資源的識別碼(以人比喻的話,相似於每個人的身分證字號的意思)。舉例來說,當你的APP包含了一個名為logo.png的圖檔(假設你存在res/drawable/資料夾中),SDK tools就會幫你在R.java這個資源類別檔裡頭自動產生一個名為R.drawable.logo的ID,讓你可以在Java程式碼中用這個ID來取得該圖檔物件。(如果在xml檔中的話就要用@drawable/logo來取得。)

  回到最佳化的話題,由於資源檔與程式碼分開管理的特性(一個在xml檔中定義,一個在Java檔中定義),我們能達到適應不同裝置組態的目標。舉例來說,你在xml中定義一個UI string時,可以用任何語言,因此你可能會有很多個語系的同一個UI string在不同的資源檔中。當你需要為你的程式附加不同語言選項時,你就可以讓系統自動去找到合適的xml檔案。比如說,利用為資源檔資料夾加入語言修飾詞(language qualifier)的動作(例如 res/values-fr/xml資源檔案),再加上使用者裝置的語言設定(前例為法文,-fr),Android系統可以幫你決定適當的xml檔案,再生成你的UI。

  為不同的資源檔版本,Android支援許多不同的修飾詞。這些修飾詞可以是添加在資源目錄的短字串以決定適當的裝置組態,如上述的-fr可以讓系統知道這是定義法文版本的xml資源的資料夾。另一個例子,你可能需要產生不同的佈局檔以應付不同的手機螢幕方向/尺寸,舉例而言,當螢幕放直(portrait orientation)時,你可能想要一些按鈕佈局改為垂直方向;當螢幕橫放時(landscape orientation)時,按鈕要放水平。這些都能透過適當的修飾詞讓系統自動決定。
  想知道更多你可以加入程式的資源類型和不同的組態下的資源檔要如何產生可以參考這裡:Providing Resources
  關於Android Fundamentals的介紹就到這邊,謝謝各位觀看。希望沒有太難懂......其實我寫這些文章一大部分是要以後自己看的,我就是上一篇文章中提到的目標觀眾"有一點基礎,但是希望知道更多的人"。希望能和也在學習或老手複習的人一起變強,所以有任何的疑問或是建議也請大家多多提出~
前年暑假去東京玩,在橫濱拍的照片XD





沒有留言:

張貼留言