> 激活組件: intents 當(dāng)ContentResolver接收到一個請求時,運行content providers。其他三個組件activities、services、broadcast receiver被Intents異步消息啟動。intent 里包含著所傳遞消息的內(nèi)容。對于activity和services來說,intents定義了請求,指定了目標(biāo)數(shù)據(jù)的URI。例如,可以讓發(fā)送一個請求讓用戶接受或者輸入一些文本信息。對broadcast receivers來說,intents定義了一些聲明的事件(?),例如:他可以在相機的按鈕被按下時發(fā)出一些信息。 下面是每個組件類型對應(yīng)的啟動方法 @ Context.startActivity() 和 Activity.startActivityForResult()方法可以啟動一個activity。activity可以查看啟動他的的intent,通過調(diào)用getIntent()方法。Android 系統(tǒng)調(diào)用onNewIntent()方法來傳遞intents。 一個activity經(jīng)常會啟動下一個activity。使用startActivityForResult() 代替 startActivity()方法可以從啟動的activity獲取一些返回值。例如,可以啟動一個activity讓用戶選擇一張圖片并且返回所選的圖片,被傳遞回來的數(shù)據(jù)被送到前一個activity的onActivityResult()方法里。 @ Context.startService()可已啟動一個service。Android通過service的onStart()方法傳遞intent對象。類似的,intent可以傳遞至Context.bindService()來獲取一個正在運行的服務(wù)的句柄,這個服務(wù)可通過onBind()方法獲取這個intent對象(如果服務(wù)沒有啟動可以通過bindService()來啟動服務(wù))。例如,一個activity可以很容易的建立一個到音樂播放服務(wù)的連接,他可以提供給用戶一些控制音樂播放器的借口。activity可以調(diào)用bindService()方法來建立連接,然后調(diào)用已經(jīng)定義的關(guān)于播放器的一些方法。 @ 應(yīng)用程序可以通過傳遞intent來初始化一個Broadcast廣播,相關(guān)方法:Context.sendBroadcast()、Context.sendOrderedBroadcast()、Context.sendStickyBroadcast() ,activity會調(diào)用所有對此廣播關(guān)注的廣播接收器,然后將intent傳遞給這些方法。 關(guān)閉組件 只有當(dāng)內(nèi)容提供商從內(nèi)容接收者接收到一個請求時才會啟動。廣播消息接受者只有當(dāng)接收到一個廣播消息時才會被啟動。所以他們不需要手動關(guān)閉。 activity則另當(dāng)別論,他們提供給用戶界面,他們和用戶保持長時間的對話并且保持活躍狀態(tài),甚至空閑時,仍然保持聯(lián)系。類似的,services也會運行很長一段時間。所以Android提供關(guān)閉activity和services的一些方法: @ finish()會關(guān)閉activity,那些被startActivityForResult()方法啟動的activity可以通過finishActivity()關(guān)閉。 @ services 可以通過 stopSelf()和Context.stopService() 方法被關(guān)閉。 當(dāng)系統(tǒng)不再使用他們或者沒有足夠內(nèi)存世,系統(tǒng)可以自行關(guān)閉一些組件,后面的章節(jié)會討論這種情況。 manifest 文件 在Android啟動一個應(yīng)用組件前,必須讓activity知道那些組件的存在,所以應(yīng)用程序必須在manifest文件里聲明自己的組件,并把manifest文件打包到Android 包里。apk文件包含程序的代碼、文件和資源。 manifest是一個結(jié)構(gòu)化的xml文件,被命名為AndroidManifest.xml,里面聲明了應(yīng)用的組件、一些除了系統(tǒng)默認(rèn)庫的用戶自定義庫和程序希望被授予的一些權(quán)限。 manifest主要任務(wù)是告訴Android應(yīng)用程序的部件。例如,activity可以這樣聲明: - view plaincopy to clipboardprint?
<?xml version="1.0" encoding="utf-8"?>
<manifest . . . >
<application . . . >
<activity android:name="com.example.project.FreneticActivity"
android:icon="@drawable/small_pic.png"
android:label="@string/freneticLabel"
. . . >
</activity>
. . .
</application>
</manifest>
復(fù)制代碼 <activity>元素的name屬性是繼承自activity基類的activity的類名,icon和label指向了資源文件。別的組件聲明起來就簡單的多了。服務(wù)的標(biāo)簽:<service>,廣播接受者標(biāo)簽:<receiver>,內(nèi)容提供商標(biāo)簽:<provider>。activity、services和內(nèi)容提供商不在這里聲明的話是不能運行的。然而,廣播可以在manifest文件里聲明或者動態(tài)的在代碼里創(chuàng)建并且調(diào)用Context.registerReceiver()方法聲明。Intent filtersIntent對象可以顯示的定義一個目標(biāo)組件。那樣的話,Android就可以找到并運行它。如果目標(biāo)組件沒有明確的定義出來,Android會相應(yīng)最佳的組件來響應(yīng)這個Intent,這是通過比較<intent filters>標(biāo)簽里的所有組件來選擇相應(yīng)的。intent filters (Intent過濾器)告訴Android所有可以處理的組件。和組件的其他重要信息一樣,在manifest文件里聲明。下面是一個添加了兩個Intents過濾器的例子: - view plaincopy to clipboardprint?
<?xml version="1.0" encoding="utf-8"?>
<manifest . . . >
<application . . . >
<activity android:name="com.example.project.FreneticActivity"
android:icon="@drawable/small_pic.png"
android:label="@string/freneticLabel"
. . . >
<intent-filter . . . >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter . . . >
<action android:name="com.example.project.BOUNCE" />
<data android:mimeType="image/jpeg" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
. . .
</application>
</manifest>
復(fù)制代碼例子中的第一個過濾器是常見的。他標(biāo)記了所有顯示給用戶讓用戶選擇啟動的組件。換句話說就是程序的入口點。是用戶啟動程序后最先見到的。第二個過濾器聲明了可以提供(perform)的特殊數(shù)據(jù)類型。(對否?呵呵)一個組件可以有數(shù)個Intent過濾器。每一個都可以聲明不同的權(quán)限。如果沒有添加過濾器的話,只能使用Intent方式被啟動。對于廣播接受者來說,如果在代碼中被創(chuàng)建和注冊,那么直接被實例化成一個IntentFilters對象,其他的過濾器都在manifest文件里被聲明。
|