還是回到 Eclipse 中,首先展開 HelloWorld 專案,你會看到如圖 1.17 所示的目錄結構。
圖 1.17
一開始看到這麼多陌生的東西,你一定會感到有點頭暈吧。別擔心,我現在就對上圖中 的內容一一講解,你很快再看這張圖就不會感到那麼吃力了。
1. src
毫無疑問,src 目錄是放置我們所有 Java 程式碼的地方,它在這裡的含義和普通 Java 專案下的 src 目錄是完全一樣的,展開之後你將看到我們剛才建立的 HelloWorldActivity 檔案就在裡面。
2. gen
這個目錄裡的內容都是自動生成的,主要有一個 R.java 檔案,你在專案中新增的任 何資源都會在其中生成一個相應的資源 id。這個檔案永遠不要手動去修改它。
3. assets
這個目錄用得不多,主要可以存放一些隨程式打包的檔案,在你的程式執行時可以 動態讀取到這些檔案的內容。另外,如果你的程式中使用到了 WebView 載入本地網頁 的功能,所有網頁相關的檔案也都存放在這個目錄下。
4. bin
這個目錄你也不需要過多關注,它主要包含了一些在編譯時自動產生的檔案。其中 會有一個你當前專案編譯好的安裝包,展開 bin 目錄你會看到 HelloWorld.apk,把這個 檔案拷到手機上就可以直接安裝了。
5. libs
如果你的專案中使用到了第三方 Jar 包,就需要把這些 Jar 包都放在 libs 目錄下,放 在這個目錄下的 Jar 包都會被自動新增到構建路徑裡去。你可以展開上圖中 Android 4.0、
Android Private Libraries、Android Dependencies 這些庫,其中顯示的 Jar 包都是已經被
新增到構建路徑裡的。
6. res
這個目錄下的內容就有點多了,簡單點說,就是你在專案中使用到的所有圖片、布 局、字串等資源都要存放在這個目錄下,前面提到的 R.java 中的內容也是根據這個目 錄下的檔案自動生成的。當然這個目錄下還有很多的子目錄,圖片放在 drawable 目錄下, 佈局放在 layout 目錄下,字串放在 values 目錄下,所以你不用擔心會把整個 res 目錄 弄得亂糟糟的。
7. AndroidManifest.xml
這是你整個 Android 專案的配置檔案,你在程式中定義的所有四大元件都需要在這 個檔案裡註冊。另外還可以在這個檔案中給應用程式新增許可權宣告,也可以重新指定你 建立專案時指定的程式最低相容版本和目標版本。由於這個檔案以後會經常用到,我們 用到的時候再做詳細說明。
8. project.properties
這個檔案非常地簡單,就是通過一行程式碼指定了編譯程式時所使用的 SDK 版本。 我們的 HelloWorld 專案使用的是 API 14,你也可以在這裡改成其他版本試一試。 這樣整個專案的目錄結構就都介紹完了,如果你還不能完全理解的話也很正常,畢竟裡
面有太多的東西你都還沒接觸過。不用擔心,這並不會影響到你後面的學習。相反,等你學 完整本書後再回來看這個目錄結構圖時,你會覺得特別地清晰和簡單。
接下來 我們一起 分析一下 HelloWorld 專案究 竟是怎麼 執行起來 的吧。首先 打 開
AndroidManifest.xml 檔案,從中可以找到如下程式碼:
<activity android:name="com.test.helloworld.HelloWorldActivity" android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
這段程式碼表示對 HelloWorldActivity 這個活動進行註冊,沒有在 AndroidManifest.xml 裡 註冊的活動是不能使用的。其中 intent-filter 裡的兩行程式碼非常重要,<action android:name= "android.intent.action.MAIN" />和<category android:name="android.intent.category.LAUNCHER" /> 表示 HelloWorldActivity 是這個專案的主活動,在手機上點選應用圖示,首先啟動的就是這 個活動。
那 HelloWorldActivity 具體又有什麼作用呢?我在介紹 Android 四大元件的時候說過,
活動是 Android 應用程式的門面,凡是在應用中你看得到的東西,都是放在活動中的。因此
你在圖 1.15 中看到的介面,其實就是 HelloWorldActivity 這個活動。那我們快去看一下它的 程式碼吧,開啟 HelloWorldActivity,程式碼如下所示:
public class HelloWorldActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hello_world_layout);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.hello_world, menu);
return true;
}
}
首先我們可以看到,HelloWorldActivity 是繼承自 Activity 的。Activity 是 Android 系統提 供的一個活動基類,我們專案中所有的活動都必須要繼承它才能擁有活動的特性。然後可以 看到 HelloWorldActivity 中有兩個方法,onCreateOptionsMenu()這個方法是用於建立選單的, 我們可以先無視它,主要看下 onCreate()方法。onCreate()方法是一個活動被建立時必定要執 行的方法,其中只有兩行程式碼,並且沒有 Hello world!的字樣。那麼圖 1.15 中顯示的 Hello world! 是在哪裡定義的呢?
其實 Android 程式的設計講究邏輯和檢視分離,因此是不推薦在活動中直接編寫介面的, 更加通用的一種做法是,在佈局檔案中編寫介面,然後在活動中引入進來。你可以看到,在 onCreate()方法的第二行呼叫了 setContentView()方法,就是這個方法給當前的活動引入了一 個 hello_world_layout 佈局,那 Hello world!一定就是在這裡定義的了!我們快開啟這個檔案 看一看。
布 局 文 件 都 是 定 義 在 res/layout 目 錄 下 的 , 當 你 展 開 layout 目 錄 , 你 會 看 到
hello_world_layout.xml 這個檔案。開啟之後程式碼如下所示:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".HelloWorldActivity" >
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" />
</RelativeLayout>
現在還看不懂?沒關係,後面我會對佈局進行詳細講解的,你現在只需要看到上面程式碼 中有一個 TextView,這是 Android 系統提供的一個控制元件,用於在佈局中顯示文字的。然後你 終於在 TextView 中看到了 hello world 的字樣,哈哈終於找到了,原來就是通過 android:text= "@string/hello_world"這句程式碼定義的!咦?感覺不對勁啊,好像圖 1.15 中顯示的是 Hello world!,這感嘆號怎麼沒了,大小寫也不太一樣。
其實你還是被欺騙了,真正的 Hello world!字串也不是在佈局檔案中定義的。Android 不 推 薦 在 程 序 中 對 字 符 串 進 行 硬 編 碼 , 更 好 的 做 法 一 般 是 把 字 符 串 定 義 在 res/values/strings.xml 裡,然後可以在佈局檔案或程式碼中引用。那我們現在開啟 strings.xml 看 一下,裡面的內容如下:
<resources>
<string name="app_name">Hello World</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
</resources>
這下沒有什麼再能逃出你的法眼了,Hello world!字串就是定義在這個檔案裡的。並且 字串的定義都是使用鍵值對的形式,Hello world!值對應了一個叫做 hello_world 的鍵,因此 在 hello_world_layout.xml 佈局檔案中就是通過引用了 hello_world 這個鍵,才找到了相應的值。
這個時候我無意中瞄到了這個檔案中還有一個叫做 app_name 的鍵。你猜對了,我們還 可以在這裡通過修改 app_name 對應的值,來改變此應用程式的名稱。那到底是哪裡引用了 app_name 這個鍵呢?開啟 AndroidManifest.xml 檔案自己找找去吧!
1.3.4 詳解專案中的資源
如果你展開 res 目錄看一下,其實裡面的東西還是挺多的,很容易讓人看得眼花繚亂, 如圖 1.18 所示。
圖 1.18
看到這麼多的資料夾不用害怕,其實歸納一下,res 目錄就變得非常簡單了。所有以 drawable 開頭的資料夾都是用來放圖片的,所有以 values 開頭的資料夾都是用來放字串的, layout 資料夾是用來放佈局檔案的,menu 資料夾是用來放選單檔案的。怎麼樣,是不是突然 感覺清晰了很多?之所以有這麼多 drawable 開頭的資料夾,其實主要是為了讓程式能夠相容 更多的裝置。在製作程式的時候最好能夠給同一張圖片提供幾個不同解析度的副本,分別放 在這些資料夾下,然後當程式執行的時候會自動根據當前執行裝置解析度的高低選擇載入哪 個資料夾下的圖片。當然這只是理想情況,更多的時候美工只會提供給我們一份圖片,這時 你就把所有圖片都放在 drawable-hdpi 資料夾下就好了。
知道了 res 目錄下每個資料夾的含義,我們再來看一下如何去使用這些資源吧。比如剛 剛在 strings.xml 中找到的 Hello world!字串,我們有兩種方式可以引用它:
1. 在程式碼中通過 R.string.hello_world 可以獲得該字串的引用;
2. 在 XML 中通過@string/hello_world 可以獲得該字串的引用。 基本的語法就是上面兩種方式,其中 string 部分是可以替換的,如果是引用的圖片資源
就可以替換成 drawable,如果是引用的佈局檔案就可以替換成 layout,以此類推。這裡就不 再給出具體的例子了,因為後面你會在專案中大量地使用到各種資源,到時候例子多得是呢。 另 外 跟 你 小 透 漏 一 下 , HelloWorld 項 目 的 圖 標 就 是 在 AndroidManifest.xml 中 通 過 android:icon="@drawable/ic_launcher"來指定的,ic_launcher 這張圖片就在 drawable 資料夾下, 如果想要修改專案的圖示應該知道怎麼辦了吧?