特别聲明:本系列文章<b>LiAnLab.org</b>著作權所有,轉載請注明出處。作者系<b>LiAnLab.org</b>資深Android技術顧問吳赫老師。
上節講述了應用程式設計的背景,本節主要講述Android應用的程式設計思想。
Android 的系統設計,與别的智能手機作業系統有很大差別,甚至在以往的任何作業系統裡,很難找到像Android這樣進行全面地系統級創新的作業系統。從創新層面 上來說,Android程式設計上的思想和支援這種應用程式運作環境的系統,這種理念本身就是一種大膽的創新。
整個Android系統,實際主要目的,就是打造一個功能共享的世界。
功 能共享最重要的互動,于是Android創造出一種Intent和IntentFilter配合的低耦合的互動模型,Intent隻是一種描述要完成什麼 工作跨程序的結構體,而最終如何解析這些Intent并完成其響應,是由IntentFilter來進行換算,最終是由使用者來決定如何完成。
而在Intent這種超級互動消息之上,Android進一步把應用程式的實作邏輯拆分成多種特殊的實作:
Þ Activity:帶顯示與互動能力的部分
Þ Service:不帶顯示與互動能力的部分
Þ Content Provider:在功能互動之外,提供資料互動能力的部分
Þ Broadcast Receiver:用來處理廣播互動的部分
這四種功能上的拆分,也展現了Android設計者在設計上抽象思緒能力,即便是随着Android迅猛發展,目前已經到了4.1這麼功能豐富、使用者體驗良好的狀态,我們程式設計也還是與這四種功能元件打交道,可以滿足我們任何的程式設計時所需要的任何行為。
而這四種基本元件組成部分,使Android應用程式反倒成了一個“空殼子”。靜态上看,應用程式隻是一種包裝這些功能的容器;從運作态來看,所謂的應用程式,也隻是承載某些功能的程序。
<b>1.1 所謂的Android應用程式</b>
我們從前面的例子中看到,無論是編寫的代碼,還是最後生成的.apk檔案,都是沒有所謂的應用程式的。應用程式本身是一種虛無的概念,隻是一種以zip格式進行壓縮的一個檔案,一種容器而已。
<a target="_blank" href="http://blog.51cto.com/attachment/201208/204746655.png"></a>
如 我們前面的Helloworld的例子裡所看到的那樣,其實一個應用程式裡最重要的一個配置檔案就是AndroidManifest.xml檔案。一個最 簡單的項目,除了基本的代碼與UI資源,也會需要有個AndroidManifest.xml檔案。甚至一些極端一點的例子,我們去市場上下載下傳一些什麼主 題包、插件包、權限包之類的.apk檔案,解壓開,這時可以發現這樣的.apk檔案裡,連代碼都沒有,隻有一些圖檔之類的檔案。
于是,我們 可以得到Android裡關于應用程式的第一個印象,作為Android應用程式的載體,.apk檔案隻是一種進行包裝與傳輸的格式,而每個.apk檔案 必然包含一個AndroidManifest.xml檔案,由這一檔案來描述該.apk檔案提供的内容。當然,我們在稍後會看到,這一檔案裡,還會包含一 些權限控制的資訊。
我們可以給我們的應用程式建立兩個一模一樣的圖形界面,直接從我們的前面的HelloWorld開始下手,比如将 HelloWorld.java在Eclipse裡拷貝到HelloAgain.java(這樣可以減少改代碼的麻煩)。這時可以得到兩個界面的應用程 序,然後我們再把我們的AndoridManifest.xml檔案,改成如下的樣子:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.lianlab.hello"
android:versionCode="1"
android:versionName="1.0">
<applicationandroid:label="@string/app_name">
<activity android:name=".Helloworld"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<b> <activity android:name=".HelloAgain"</b>
<b> android:label="@string/app_name"></b>
<b> <intent-filter></b>
<b> <action android:name="android.intent.action.MAIN"/></b>
<b> <category android:name="android.intent.category.LAUNCHER"/></b>
<b> </intent-filter></b>
<b> </activity> </b>
</application>
</manifest>
這時我們編譯、安裝到Android裝置(或者是虛拟機)裡,這時再打開主界面檢視安裝過的應用程式,這時是不是發生了什麼很奇怪的現象?這時界面上會出現 兩個叫Helloworld的應用程式。我們這時如果在裝置裡去“設定”à “應用程式”,我們仍隻看到一個應用程式。
通過對 AndroidManifest.xml的小惡作劇,我們可以看到Android應用程式的第二個特點,就是沒有所謂的主入口(即我們點選的圖示時觸發的 執行效果)。應用程式在安裝完成後,隻是通過AndroidManifest.xml來決定在系統上應該表現成什麼樣子。
如果希望應用程式 可以表現不如此變态,這時,我們可以回到AndroidManifest.xml裡, 把<activityandroid:name=".HelloAgain"…這個标簽裡的<intent-filter>标簽删掉, 這時應用程式的表現就正常了。
到目前為止,我們就已經接觸了android程式設計裡的兩個概念,一個是Activity,另一個是 Intent(而我們AndroidManifest.xml檔案裡的Intent Filter實際是輔助Intent的)。Android畢竟是種圖形界面的程式設計環境,我們常見的應用程式裡,可能絕大部分隻會與這兩種概念打交道。而兩 者的概念組合,就很容易展現出Android應用程式在程式設計上的“無界化”思想。
<b>1.2 Android世界裡的共享</b>
<b> </b>
作 為一個智能手機作業系統,其使用者可能在功能上有各種各樣的功能組合。比如最簡單的打電話,則後續動作會有儲存聯系人,同時需要給聯系人拍照做來電大頭貼。 又比如需要來了個短信通信使用者到某個地方幹什麼事情,這時,使用者需要打開地圖,搜尋一下位址,然後還有可能需要定位到那個位置。
<a target="_blank" href="http://blog.51cto.com/attachment/201208/204955584.png"></a>
使用者在主界面裡點選相應功能的應用程式之後,就可能有非常多的功能性的組合,因為使用者的想法是不可預估的。我們當然也可以限制使用者目前菜單下可以幹什麼事情,但這樣就失去了智能系統的意義。
我 們也可以假設使用者都會按一個“Home”鍵回到主界面,這時原來的執行的程式就會被鎖定目前狀态,使用者重新打開另外一個應用程式,操作完再按“Home” 鍵可以退回到原來的應用程式。通過這種“應用程式”到“Home”到“應用程式”的循環,我們也可以達到我們想要達到的目的。但這時,出于互動性的考慮, 我們也還是需要有限地提供一些互動手段,比如“短信”應用程式裡包含位址資訊,一點選可以直接打開“地圖”進行後續操作,但這些有限互動是可以在系統設計 階段被固化。這時,我們是不是就得到了我們想要的能夠應付使用者任何操作組合的系統?是的,恭喜您,您得到了iPhone的設計思路。但此時的使用者互動流程 則被改變成這個樣子:
<a target="_blank" href="http://blog.51cto.com/attachment/201208/205050175.png"></a>
這種解決問題的辦法也不是不可以,但需要很固化的設計,應用程式的行為比較受限。雖然通過橫掃全世界的 iPhone證明了這樣的設計可能是比較合乎使用者體驗之道的(不容易出錯),但這樣的解決思路從系統設計角度來看,并不是很靈活。另外一個麻煩是必須要有 蘋果級設計功底的“Home”鍵,山寨貨則用不了多久就會因為鍵盤失靈而失效。當然即使蘋果級設計,iPhone裡的“Home”鍵還是會失效,于是又不 得不在螢幕上加上觸摸的Home手勢。
作為開源系統的Android,當然不可能基于iOS的互動思路來解決問題,何這種互動時多了一步不 停要回到主界面這一步。在Android的設計裡,最重要的是能夠解決一個應用程式之間進行互動的問題,然後可以實作我們想要在Android系統裡完成 某種操作時,可以享受從一路順暢完成的快感。
Android的解決之道,則是将傳統意義上的應用程式,細化成一個個完成某項功能的部分,這 種功能部分,在Android世界裡被稱為Activity。Activity都應該被設計成可以獨立地被執行以解決某個問題,當它完成或是使用者選擇退出 執行時,又會自動跳回到調用這一Activity的界面,當然這時跳回的位置肯定是另外一個Activity。當然,在一個Android系統裡有可能存 在無限多的Activity,在他們進行跳轉切換時,我們就需要一種很靈活的消息傳輸機制(因為我們必須相容系統裡所有可能的互相調用的情況)。而且這種 傳輸機制還必須能夠跨程序,不然,我們所有的涉及Activity互相調用部分都必須在同一程序裡完成。于是,Android系統裡又有了Intent, 用于解決互動通信。
<a target="_blank" href="http://blog.51cto.com/attachment/201208/205152678.png"></a>
這樣的程式設計模型也需要有一定前提,那就是我們Application概念必須被弱化,我們不能有main 函數入口(如果系統執行依賴main作入口,則不能實作Activity之間互相調用了,所有的Activity執行之前,必須先通過main入口來初始 化環境)。出于這樣的設計,是以Application必須隻是一個容器,将各種不同的Activity實作包裝起來加載到系統裡。
當然, 将功能拆分成一個個的單一功能界面之後,我們需要有種機制可以将使用者一路點選過去曆史記錄下來,當使用者處理完時,可以退回到他們之前操作過的界面,這次就 可以由多個應用程式組合出像是在用同一個應用程式的效果。有了Activity,有了Activity之間起到調用作用的Intent,這時所有界面間操 作變得有點像是函數調用一樣,于是我們可以找函數調用時的基本資料結構—棧來幫忙,發生調用時,需要退出的Activity及其狀态壓棧,當從調用退出時 則進行棧的彈出操作,這時我們的Activity管理就演變成如下圖所示的簡單棧管理。
<a target="_blank" href="http://blog.51cto.com/attachment/201208/205300979.png"></a>
有了這樣的概念,于是我們響應使用者點 擊操作的問題便迎刃而解,我們在設計應用程式時,不再是設計一個複雜的功能實作,而是實作一組完成單項功能的實作,也就是Activity。然後這些 Activity,隻會通過使用者點選來驅動它們之間是如何進行互動的。比如,我們前面看到的地圖、搜尋、定位三個功能,雖然它都會被包裝到同一個地圖的應 用程式裡,但在實作上會是地圖、搜尋、定位三個不同的Activity。
因為現在我們的界面上的互相調用,已經變成了一種函數式的調用,這 樣,整個手機上的功能都被切分成各個單一的小功能,而真正要在Android系統上完整地實作某複雜個操作,則會送出由使用者的點選來組合生成。這樣的複雜 功能,則已經不是一個程式設計上的概念了,在Android系統裡,這種需要完成什麼事情的操作被抽象成一個虛拟的概念Task。比如我們前面提到的打電話加 拍大頭貼的操作組合,就構成一個Task,這一Task需要由Launcher.apk,Contacts.apk,Gallery.apk來協同完成。
<a target="_blank" href="http://blog.51cto.com/attachment/201208/205342267.png"></a>
如 果我們有兩個能夠提供同樣功能的Activity,這種執行模式的靈活性表現得會更加明顯。比如中間打電話的功能,我們系統裡有三個 Activit(CallScreen, SipPhone, Dialer)都可以完成電話呼叫的功能,這時執行上的路徑則會有三種可能性,會在進行跳轉時彈出對話框由使用者來選擇:
<a target="_blank" href="http://blog.51cto.com/attachment/201208/205441536.png"></a>
通 過Activity的這種可以動态被使用者選擇的特點,當使用者對某一功能不滿意時,完全就有可能通過下載下傳另一個能實作這種功能的應用程式進行替換,甚至可以 自己寫一個。事實上,Android系統裡除了系統狀态條與鎖屏界面之後,沒有任何的不可被替換的功能,這也是Android裝置總是會長得千奇百怪的原 因之一。
到這時,我們就可以看到Activity之是以會不被稱為Window的原因,它也是單個界面或是MVC裡的Controller 實作部分那麼簡單,Activity這個名字代表的是某種單一互動功能上的實作。這種功能的實作将在系統裡通過Intent串接起來,構成了一個在功能上 具備極大可拓展性的系統。基于這樣的特點,Android也就被稱作是“無邊界”系統,因為它在功能上延展不再受限于系統的能力,而隻受限于智商與創意。
這就是Android世界裡的功能共享。
在這種功能共享模型之下,可能還是會有一些微調的需求:
1. 我 們有一些情況下不宜使用這種棧式Activity管理,比如我們寫一個需要注冊的應用程式,注冊完開始使用,然後再按退出,我們又會一步步退回到注冊填個 人資訊的界面,而不合理地完全退出。這樣可能不合适。這時,我們可以使用Intent的Flag參數, 加上Activity的Affinity屬性進行組合控制。
2. 如果不停地跳出對話框讓使用者選,使用者會崩潰掉。 當然,使用者可以在選擇時點選一個“始終”的預設選擇,這時下次就會使用預設的Activity處理某種操作。但還是有可能會不合理地使用跨.apk檔案裡 使用Activity,造成性能上的開銷,這時,我們也可以在執行下次Activity執行操作時進行強制性地指定。
當然,我們通過 Activity這種概念還需要另外一個前提,這就是Android會有别于傳統作業系統的前提,那就是單視窗。想像一下,在多視窗環境下,我們的棧式管 理Activity在進行跳轉和傳回時将會構成多大的災難啊。好在使用電容屏的裝置,單視窗是天生的需求。由于手指觸摸的精度非常低,無法點準過小的按 鈕,比如視窗上的關閉按鈕,如果将這些按鈕放大,又造成了螢幕顯示空間上的浪費。iPhone帶來的“後PC時代”革命,最重要的一點就是使用“返祖”式 的單視窗顯示。
這種怪異的操作方式,實際上在我們生活中也有類似的例子,就比如說我們的動态網頁。動态網頁,特别是HTML5建構的網絡應 用程式,其操作模式,就是可以在不同的連結裡不斷地點選下去,如果不是彈出新視窗,我們始終還可以退回到發起這一連串點選的起始頁面。Android應用 程式,XML構成的UI語言的作用跟Html頁面類似,而Java建構的Activity就相當與網頁互動中使用的JavaScript,有了這樣的相似 性,Android程式設計環境可以說是最接近HTML5的一種程式設計環境了,但可惜不能像HTML5那樣可以跨平台。
我們解析了能完成單一功能 的Activty,這時還需要了解Intent,就像是我們了解過了函數實作原理,我們還需要掌握函數之間的參數傳遞。當然,一般在介紹程式設計的思路裡,會 結合起來說明,或是先說明參數傳遞。但Android環境裡有點特殊性,一是Intent是一種能夠實作跨程序調用的資訊傳遞機制,二是Intent在消 息傳遞上又很靈活,有一定的動态性。Intent不光服務于Activity之間的調用,還會用于一些不直接與界面打交道的邏輯實作部分,比如我們後面将 提到的Service,Broadcast Receiver,以及 Notification。
<b>1.3 Intent與Intent Filter</b>
Intent, 英文原意就是要“幹什麼”的意思,之是以取這個名字,也是因為在Android系統裡,Intent所起到的作用就是用來指明下一步具體是做什麼,具體是 不是執行,由誰來執行,則會由根據目前的系統狀态(能不能解析這個Intent請求)來決定。這不隻是簡簡單單地發個消息而已,而是一種更安全的、更加松 散的消息機制。
在一個Intent消息對象裡,共有六個成員(并不都是必須指派的,隻要一個Intent對象能夠被解析,就會得以執行,否則就會會被舍棄):
成員
類型
說明
示例
<b>ComponentName</b>
String
用于定義誰将處理這一Intent。它由一個Activity的具體實作的全名(加上包名)來指定
org.lianlab.hello.HelloActivity
<b>Action</b>
用于定義這一動作是做什麼,可以被拓展自定義類型
ACTION_CALL
開始通話.
ACTION_EDIT 進行編輯.
<b>Data</b>
用一個URI來指定Intent的操作對象,因為URI一般會包含種類資訊,于是這個值也可能被用作MIME設别。
“content://contacts/people/1”
指定聯系清單中的第一個
<b>Category</b>
用來進一步明确什麼樣的可執行實體将處理這一Intent。是可選項,也可多選。
CATEGORY_HOME
主界面應用程式
CATEGORY_LAUNCHER
可在主界面裡被點選
<b>Type</b>
用來指定特定的MIME類型
"video/*"
視訊
<b>Extra</b>
Bundle
用來傳遞額外的資料傳遞,前面我們也介紹了Bundle是一種key:value配對的字典類型,于是Extra裡可以轉遞複雜的資料
putExtra("sms_body", "some text");
發短信時指定内容
<b>Flags</b>
int
預定義一系列用來控制Intent行為的屬性值
在 這個成員變量裡,最能展現靈活性的就是Component,如果指定了這個值,則我們在通過startActivity()方法來發送Intent時,就 會自動啟動Component指定的Activity。如果沒有指定,則會由系統來選擇一個能夠處理這一Intent的Activity來執行,這時就引 入了Intent Filter的概念。
Intent Filter在Android裡是一種類似于Windows裡的系統資料庫一樣的東西,雖然我們也可以通過程式設計來進行Intent Filter的控制,但一般情況下,我們隻在AndroidManifest.xml檔案裡進行定義,對它一個<intent- filter>的标簽進行指定。應用程式在安裝過程中,它的AndroidManifest.xml會被系統掃描并彙總到系統環境裡,這 時<intent-filter>也會被導入。當Activity發送出來的Intent,沒有指定Component時,系統就會通 過<intent-filter>找到合适的處理對象,如果隻有一個或是使用者設定了預設項,則啟動這個功能部件來完成任務;如果有多 個<intent-filter>比對同時使用者又沒有指定預設項,則會彈出對話框讓使用者選擇。當然,預設項也會随着系統裡新增了同一 Intent比對項而失效,使用者也可以通過“設定”à “應用程式”來取消預設值。
在AndroidManifest.xml裡面定義<intent-filter>很簡單,就是通過指定Intent對象的Action,Data,Type,和Category這四個成員變量來指定。比如:
<activityandroid:name=".PlayerActivity"android:label="@string/app_name"
android:configChanges="orientation" >
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.LAUNCHER" />
<intent-filter>
<actionandroid:name="android.intent.action.VIEW" />
<categoryandroid:name="android.intent.category.DEFAULT" />
<dataandroid:scheme="file" />
</intent-filter>
...
</activity>
我 們可以繼續修改我們前面的HelloWorld的例子,我們建立一個Intent,将Action設 成”android.intent.action.VIEW”(可以通過Intent.ACTION_VIEW這個預變量來轉義),data使用某個檔案 “file:///sd-ext/Movies/test.mp4”,這時就會比對到我們上面的<intent-filter>定義:
<b>public void</b> onClick(Viewv) {
Intent request = <b>new</b> Intent(Intent.ACTION_VIEW);
request.putData(“file:///sd-ext/Movies/test.mp4”);
startActivity(request);
finish();
}
當然,我們并不一定需要代碼來進行這樣的測試,我們也可以使用裝置上的am指令來完成。要完成與上面的點選操作一樣的功能,也可以通過adb來執行這條指令:
$adb shell am start –aandroid.intent.action.VIEW –d file:///sd-ext/Movies/test.mp4
在我們具體寫代碼過程中,我們可以根據需求來定義我們所需要的<intent-filter>,可以将過濾規則寫得很細,也可以寫得很粗,讓我們的Activity有更多地被執行到的機會。在這些規則裡,可能最重要的規則,就是我們前面也示範過的:
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
這兩行<intent-filter>規則,将使用我們的應用程式可以被主界面所收集,使使用者可以在主界面裡點選運作這個Activity。
有了Activity,我們就可以建構基于功能共享而實作所謂應用程式,而有了Intent,使用我們在共享時所受的限制可以變得更小。而且,由于是簡單化的單視窗模式,再加上一些在性能設計上的精細設計,于是我們的Android系統便有了良好的人機互動體驗。
<b>1.4 </b>程式設計<b>角度的應用程式</b>
光 有Activity與Intent,并不是Android應用程式程式設計時的全部。應用程式除了有人機互動界面之外,有可能還需要使用到一些不直接與人互動 而在背景長期運作操作;我們還需要有某種機制,能夠提供資料共享,并且在資料共享時能使用統一的通路機制;最後,我們可能還需要處理以廣播方式發送的消 息,廣播與Intent不同之處在于一到多的方式傳播,同時消息隻在某個時間段内有效。
事實上,我們的Android程式設計,是被包裝成四個不同的類型,同時通過Intent将這些類包裝起來,以解決我們上面提到的,在編寫圖形應用程式裡可能遇到的問題的:
l <b>Intent</b>: 全局性的、松散的消息傳遞機制
l <b>Activity</b>:帶圖形界面的,可以與使用者進行互動的邏輯實作。
l <b>Service</b>: 不帶圖形界面的,不直接與使用者互動的代碼。一般會被用于在背景做些什麼事情,比如監聽網絡、下載下傳、拷貝檔案等。(這可能是一般的Android工程師覺 得沒有必要實作的部分,筆者在講解Android應用程式相關的課程時,就常有問及,Actiivity會進入到背景,然後有可能被殺死掉,這樣的問題如 何解決?實際上Activity隻解決互動,需要在背景時還需要繼續執行的代碼,需要用Service來實作。隻自己可通路的Service,可以使用簡 單的本地Service,而需要提供給别的程序來通路的情況下,我們需要通過AIDL編寫Remote Service。Service的實作,我們在背景再詳細說明,因為Android系統的核心Framework,本身就是由大量這樣的Remove Service來組成的。)
l <b>Content Provider</b>: 提供資料層共享,以CRUD(Create Read Update Delete)方式進行資料通路來統一化資料讀寫指口一種模型。如果使用了Sqlite做背景的資料支援(實際上相當于應用程式MVC模型裡的Model 部分被Sqlite延展開來),我們可以通過ContentProvider來各系統内的其他部分提供資料源,當然系統本身也給我們提供了大量這樣的 ContentProvider,像Setting裡的設定的值、聯系清單、多媒體檔案掃描結果等。(這種資料層上的共享機制,也是應用程式程式設計上需要加 強的技巧之一,因為有了Content Provider,我們則有可能使用Cursor式進行通路,這時我們就可以使用CursorAdapter來自動化地處理資料源。)
l <b>Broadcast Receiver</b>: 處理廣播類消息的監聽器,進而可以給應用程式提供廣播式的資訊處理,同時也提供系統消息的廣播式分發。比如,Android會将一些系統事件廣播出來,像 電話振鈴、電量狀态變化、網絡狀态變化等,我們需要能夠處理這樣的事件,電話振鈴時我們寫的多媒體播放器就應該靜音、電量過低時需要儲存狀态等。對我們應 用程式而言,廣播方式也是一種很好的通信機制,我們不需要寫一個循環通知所有的Activity、Service我們狀态發生了改變,而隻需要發一個廣 播,則所有關心這一事件的部分都可以收到。
這些功能實體,都是我們通過Java代碼根據不同的基類(Service、 ContentProvider、BroadcastReceiver)派生出相應的子類,再加以具體實作。這樣的功能實作不需要自己去建立這個對象,會 通過AndroidManifest.xml裡的定義,由系統按執行的需要自動建立。有了這些不同的功能實體,我們最後的應用程式,實際上就成了這個樣 子:
<a target="_blank" href="http://blog.51cto.com/attachment/201208/205636704.png"></a>
而我們的所有代碼,從運作态行為來看,都不再是直接的互相調用關系,而是全部都通過Intent來進行彼此之間的互動。而這樣的互動,也不再是傳統式地自己陪自己玩,而是會進入到一個大的功能集合體時,提供功能給系統内其他應用程式所使用,而自己也會調用其他部分的代碼。
<a target="_blank" href="http://blog.51cto.com/attachment/201208/205805967.png"></a>
當然,随着Android版本變更,Android系統又新增了一些新的概念,比如針對多視窗功能的Fragment、針對于使用異步機制操作Cursor的Loader等。但萬變不離其宗,這些Android的核心原理則一直如此。
總 結一下Android程式設計思想,我們就會知道其實在Android整個生态環境最重要的元素,應用程式,反倒是Android程式設計上最不重要的。所謂的 Android程式設計,就是要通過編寫一個個的Activity、Service、Content Provider、Broadcast Receiver實作,通過功能上的共享與資料上的共享進一步豐富使用者可用的功能。當使用者可以通過Market或自己下載下傳取得我們封裝到.apk檔案裡的 實作之後,這些功能就會無縫地被Intent整合到了一起。
從Android這個程式設計原則來看,我們可以看到,如果我們使用某種Java執 行環境,将Android應用程式的這些組成部分的支援都加入進來,我們也可以得到一個Android相容的環境。的确如此,已經有人在打這方面的主意, 有将Android環境移植到Windows環境裡的BlueStack商業解決方案,也有号稱相容Android應用程式,通過一個類似于JAVA ME的虛拟機環境來支援Android應用程式的BlackBerryOS。但我們可以再來看看Android的真正的支援環境,我們可以看 到,Android有其獨特的特性,也不是那麼容易被取代。
本文轉自 21cnbao 51CTO部落格,原文連結:http://blog.51cto.com/21cnbao/975590,如需轉載請自行聯系原作者