2013年9月3日 星期二

[Android] Android Developer App Components Note 3

App Fundamentals-The Manifest File 1

(見Android Developer App Fundamentals The Manifest File)

The Manifest File

在Android系統可以開始一個app組件(component)之前,
系統必須要知道這個組件的存在。
怎麼知道呢?就是透過讀這個app的AndroidManifest.xml檔。
你的app必須要把所有的components定義在這個檔案裏頭,
而且這個檔案必須要放在你的Android專案(project)的根目錄。

Manifest除了聲明(declaring)了app的組件以外,
還做了以下幾件事情:
a. 辨認所有這個app所需要的使用者許可授權(user permissions),
比方說像是網路存取,或者是讀取使用者的通訊錄。
b. 聲明這個app所需的最低Android API Level,這是根據這個app用了哪些API。
c. 聲明這個app所需要使用的硬體和軟體功能,
像是相機、藍芽服務、或者多點觸控的螢幕。
d. 這個app所需連結的API libraries(指在Android framework APIs以外的東西),
像是Google Maps library。

Declaring components

Manifest的主要工作就是要告知系統app所用的組件。
舉例來說,一個manifest檔可以聲明一個activity如下:
<?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的圖示的資源。
<activity>元素裡,android:name屬性指定了完全相符的Activity的class的子class名字,
android:label屬性指定了一個字串(string)用以作為使用者可見的activity的標籤(label)。

你必須用這樣的方式來聲明出所有app的組件:
a. <activity>元素-> activities
b. <service>元素-> services
c. <receiver>元素-> broadcast receivers
d. <provider>元素-> content providers

上述4個,除了broadcast receivers以外,就算你將其include在原始碼(source)裡,
但卻沒有在manifest聲明的話,系統是看不見它們的,
結果就是會永遠跑不起來。但broadcast receivers是可以定義在manifest,
或者說動態的在code裡產生(作為BroadcastReceiver 物件),
且藉由呼叫registerReceiver()來向系統進行註冊。

對於如何建構你的app的manifest檔的介紹,
可以參照The AndroidManifest.xml File文件。

Declaring component capabilities

如同前面討論的那樣,在Activating Components裡,
你可以使用一個Intent來開始activities, services, 以及broadcast receivers。
你可以藉由在intent裡外顯地命名目標組件(使用組件的class名字)來達到目的。
但是,intents威力強大的地方是在於intent actions的概念。
使用它,你只要單純描述你想要執行的動作(action)
(另外可以選擇是否附帶上你想要操作的資料),
並且允許系統尋找相對應可以執行action的組件來啟動。
如果有多重的組件可以被intent所描述的動作所執行的話,
則讓使用者選擇使用哪一個來進行操作。

系統辨認可以回應到一個intent的組件的方法,
是藉由對比所收到的intent以及在裝置上其他的app的manifest檔所提供的intent filters。

當你在你的app的manifest檔裡聲明了一個組件時,
你可以選擇性地包進那些聲明組件可以做到的事情的intent filters,
藉此它可以對於從其他app傳出來的intents做出反應。
你可以藉由加入一個 <intent-filter>元素,作為組件的聲明元素的子元素,
來定義intent filter。

舉例來說,一個email的app,當中含有寫新郵件的activity,
可能定義在manifest裡,讓它對於"send" intents有反應(為了要傳送email)。
一個你的app的activity可以作出一個intent,
當中附有"send" action(ACTION_SEND)。
當你使用startActivity()來喚起(invoke) intent時,
這個action會被系統比對和email app的"send" activity相符合,
並且將其啟動。

要了解更多有關作intent filters的細節,
請參照Intents and Intent Filters文件。