Sample.apk: Zip archive data, at least v1.0 to extract
複製代碼
$file Sample.apkSample.apk: Zip archive data, at least v1.0 to extract對,沒有看錯,只一個簡單的zip文件。要是做過Java開發的人,可以對這種格式很親切,因為傳說中的.jar、.war格式,都是Zip壓縮格式的文件。我們可繼續使用unzip命令將這一文件解壓(或是任何的解壓工具,zip是人類歷史是最會古老最為普及的壓縮格式之一,幾乎所有壓縮工具都支持)。通過解壓,我們就得到了下面的文件內容:
AndroidManifest.xml,
classes.dex,
resources.arsc,
META-INF,
res,
複製代碼
到這裡,我們就可以看到一個Android應用程序結構其實是異常簡單的。這五部分內容(其中META-INF和res是目錄,其他是文件)除了META-INF是這一.apk文件的校驗信息,resources.arsc是資源的索引文件,其他三部分則構成了Android應用程序的全部。
T AndroidManifest.xml,這是每個Android應用程序包的配置文件,這裡會保存應用程序名字、作者、所實現的功能、以及一些權限驗證信息。但很可惜,在編譯完成的.apk文件裡,這些文件都被編譯成了二進製版本,我們暫時沒有辦法看到內容,後面我們可以再看看具體的內容。
T classes.dex,這則是Android應用程序實現的邏輯部分,也就是通過Java編程寫出來而被編譯過的代碼。這種特殊的格式,是Android裡特定可執行格式,是可由Dalvik虛擬機所執行的代碼,這部分內容我們也會在後續的介紹Dalvik虛擬機的章節裡介紹。
T res,這一目錄裡則保存了Android所有圖形界面設計相關的內容,比如界面應該長成什麼樣子、支持哪些語言顯示等等。
從一個android應用程序的包文件內容,我們可以看到android應用程序的特點,這也是Android編程上的一些特徵:
1 簡單:最終生成的結果是如些簡單的三種組成,則他們的編程上也不會有太大的困難性。這並不是說Android系統裡無法實現很複雜的應用程序,事實上Android系統擁有世界上僅次於iOS的應用程序生態環境,也擁有複雜的辦公軟件、大型3D遊戲。而只是說,如果要實現和構成同樣的邏輯,它必然會擁有其他格式混雜的系統更簡化的編程模式。
2 Java操作系統:既然我們編譯得到的結果,classes.dex文件,是用於Java虛擬機(雖然是Dalvik虛擬機,但實際上這一虛擬機只是一種特定的Java解析器和虛擬機執行環境 )解析執行的,於是我們也可以猜想到,我們的Android系統,必然是一個Java操作系統。我們在後面會解釋,如果把Android系統直接看成Linux內核和Java語言組合到一起的操作系統很不準確,但事實上Android,也還是Java操作系統,Java是唯一的系統入口。 使用MVC設計模式:所謂的MVC,就是Model,View,Controller的首字母組合起來的一種設計模式,主要思想就是把顯示與邏輯實現分離。Model用於保存上下文狀態、View用於顯示、而Controller則是用於處理用戶交互。三者之間有著如下圖所示的交互模型,交互只到Controller,而顯示更新只通過View進行,這兩者再與Model交換界面狀態信息:
clean Removes output files created by other targets.
debug Builds the application and signs it with a debug key.
install Installs the newly build package. Must be used in conjunction with a build target (debug/release/instrument). If the application was previously installed, the application is reinstalled if the signature matches.
installd Installs (only) the debug package.
installi Installs (only) the instrumented package.
installr Installs (only) the release package.
installt Installs (only) the test and tested packages.
instrument Builds an instrumented packaged.
release Builds the application in release mode.
test Runs tests from the package defined in test.package property
uninstall Uninstalls the application from a running emulator or device.
雖然我們只是下載了SDK,通過一行腳本創建了Android應用程序工程,通過另一行完成了編譯。但也許還是會被認為過於麻煩,因為需要進行字符界面的操作,而且這種開發方式也不是常用的方式,在Java環境下,我們有Eclipse可用。我們可以使用Eclipse的圖形化開發工具,配合ADT插件使用。 2.2 使用Eclipse+ADT插件在Android環境裡可以使用Java世界裡幾乎一切的開發工具,比如NetBeans等,但Eclipse是Android官方標準的開發方式。使用Eclipse開發,前面提到的開發所需SDK版本下載,也是必須的,然後還需要在Eclipse環境裡加裝ADT插件,Android Development Toolkit。
我們在Eclipse的菜單裡,選擇」Help」 a 「Install New Software…」,然後在彈出的對話框裡的Workwith:輸入ADT的發佈地址:https://dl-ssl.google.com/android.eclipse,回車,則會得到下面的軟件列表。選擇Select All,將這些插件全都裝上,則得到了可用於Android應用程序開發的環境。
這裡還需要指定SDK的地址,Windows或是Linux裡,會是在菜單「Window」 a 「Preferences」,在MacOS裡,則會是」Eclipse」 a「Preferences」 。在彈出的對話框裡,選擇Android,然後填入Android SDK所保存的位置。
點擊OK之後,則可以進行Android開發了。選擇」File」 a 「New」a 「Project」 a 「Android」,在Eclipse 3.x版本裡,會是「Android Project」,在Eclipse 4.x版本裡,會是「Android Application Project」。如果我們需要創建跟前面字符界面下一模一樣的應用程序工程,則在彈出的創建應用程序對話框裡填入如下的內容:
我們從這些android編程的過程,看不出來android跟別的Java編程模式有什麼區別,倒至少驗證了我們前面對android編程特點的猜想,就是很簡單。如果同樣我們使用Eclipse開發Java的圖形界面程序,需要大量地時間去熟悉API,而在Android這裡學習的曲線被大大降低,如果我們只是要畫幾個界面,建立起簡單的交互,我們幾乎無須學習編程。
而從上面的步驟,我們大概也可以得到Android開發的另一個好處,就是極大的跨平台性,它的開發流程裡除了JDK沒有提及任何的第三方環境需求,於是這樣的開發環境,肯定可以在各種不同的平台執行。這也是Android上進行開發的好處之一,跨平台,支持Windows,Linux與MacOS三種。
我們再來看一個,我們剛才創建的這個工程裡,我們怎麼樣進行下一步的開發。在Android開發裡,決定我們應用程序表現的,也就是我們從一個.apk文件裡看到的,我們實際上只需要:
T 修改AndroidManifest.xml文件。AndroidManifest.xml是Android應用程序的主控文件,類型於Windows裡的註冊表,我們通過它來配置我們的應用程序與系統相關的一些屬性。
T 修改UI顯示。在Android世界裡,我們可以把UI編程與Java編程分開對待,處理UI控件的語言,我們可以叫它UI語言,或是layout語言,因為它們總是以layout類型的資源文件作為主入口的。Android編程裡嚴格地貫徹MVC的設計思路,使我們得到了一個好處,就是我們的UI跟要實現的邏輯沒有任何必然聯繫,我們可先去調整好UI顯示,而UI顯示後台的實現邏輯,則可以在後續的步驟裡完成。
T 改寫處理邏輯的Java代碼。也就是我們MVC裡的Controller與Model部分,這些部分的內容,如果與UI沒有直接交互,則我們可以放心大膽的改寫,存在交互的部分,比如處理按鈕的點擊,取回輸入框裡的文字等。作為一個定位於拓展能力要求最高的智能手機操作系統,android肯定不會只實現畫畫界面而已,會有強大的可開發能力,在android系統裡,我們可以開發企業級應用,大型遊戲,以及完整的Office應用。
在上面IDE工具裡,左邊是控件列表,中間是進行繪製的工作區,右邊會是控件一些微調窗口。一般我們可以從左邊控制列表裡選擇合適的控件,拖到中間的工作區來組織界面,原則上的順序是layout a 復合控件 a 簡單控件。中間區域可以上面還有選擇項用於控制顯示屬性,在工作區域裡我們可以進一步對界面進行微調,也可以選擇控件點擊左鍵,於是會出來上下文菜單來操作控件的屬性。到於右邊的操作界面,上部分則是整個界面構成的樹形結構,而下部分則是當我們選擇了某個界面元素時,會顯示上下文的屬性。最後,我們還可以在底部的Graphic Layout與main.xml進行圖形操作界面與源代碼編輯兩種操作方式的切換。
Intent query = new Intent(Intent.ACTION_WEB_SEARCH);
query.putExtra(SearchManager.QUERY,
((TextView)v).getText());
startActivity(query);
finish();
}
複製代碼
但是可能還是無法解決我們對於Android應用程序與Java環境的區別的疑問:
T Android有所謂的MVC,將代碼與顯示處理分享,但這並非是標準Java虛擬機環境做不到。一些J2EE的軟件框架也有類似的特徵。
T AndroidManifest.xml與On*系列回調,這樣的機制在JAVA ME也有,JAVA ME也是使用類似的機制來運行的,難道Android是JAVA ME的加強版?
T 至於Listener模式的使用,眾所周知,Java是幾乎所有高級設計模式的實驗田,早就在使用Listener這樣模式在處理輸入處理。唯一不同的是ClickListener,難道Android也像是可愛的觸摸版Ubuntu手機一樣,只在是桌面Java界面的基礎加入了觸摸支持?
T Activity從目前的使用上看,不就是窗口(Window)嗎?Android開發者本就有喜歡取些古怪名字的嗜好,是不是他們只是標新立異地取了個Activity的名字?
對於類似這樣的疑問,則是從代碼層面看不清楚了,我們得回歸到Android的設計思想這一層面來分析,Android應用程序的執行環境是如何與眾不同的。
不過,我們可以從最後的那行Activity調用另一個Activity的例子裡看出一些端倪,在這次調用裡,我們並沒有顯式地創建新的Activity,如果從代碼直接去猜含義的話,我們只是發出了個執行某種操作的請求,而這個請求並沒有指定有誰來完成。這就是Android編程思想的基礎,一種全開放的「無界化」編程模型。