> 編寫:[riverfeng](https://github.com/riverfeng) - 原文:[http://developer.android.com/training/multiscreen/screensizes.html](http://developer.android.com/training/multiscreen/screensizes.html)
這節課教你如何通過以下幾種方式支持多屏幕:
1、確保你的布局能自適應屏幕
2、根據你的屏幕配置提供合適的UI布局
3、確保正確的布局適合正確的屏幕。
4、提供縮放正確的位圖(bitmap)
### 使用“wrap_content”和“match_parent”
為了確保你的布局能靈活的適應不同的屏幕尺寸,針對一些view組件,你應該使用wrap_content和match_parent來設置他們的寬和高。如果你使用了wrap_content,view的寬和高會被設置為該view所包含的內容的大小值。如果是match_parent(在API 8之前是fill_parent)則會匹配該組件的父控件的大小。
通過使用wrap_content和match_parent尺寸值代替硬編碼的尺寸,你的視圖將分別只使用控件所需要的空間或者被拓展以填充所有有效的空間。比如:
~~~
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:layout_width="match_parent"
android:id="@+id/linearLayout1"
android:gravity="center"
android:layout_height="50dp">
<ImageView android:id="@+id/imageView1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/logo"
android:paddingRight="30dp"
android:layout_gravity="left"
android:layout_weight="0" />
<View android:layout_height="wrap_content"
android:id="@+id/view1"
android:layout_width="wrap_content"
android:layout_weight="1" />
<Button android:id="@+id/categorybutton"
android:background="@drawable/button_bg"
android:layout_height="match_parent"
android:layout_weight="0"
android:layout_width="120dp"
style="@style/CategoryButtonStyle"/>
</LinearLayout>
<fragment android:id="@+id/headlines"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.HeadlinesFragment"
android:layout_width="match_parent" />
</LinearLayout>
~~~
注意上面的例子使用wrap_content和match_parent來指定組件尺寸而不是使用固定的尺寸。這樣就能使你的布局正確的適配不同的屏幕尺寸和屏幕方向(這里的配置主要是指屏幕的橫豎屏切換)。
例如,下圖演示的就是該布局在豎屏和橫屏模式下的效果,注意組件的尺寸是自動適應寬和高的。

圖1:News Reader示例app(左邊豎屏,右邊橫屏)。
### 使用相對布局(RelativeLayout)
你可以使用LinearLayout以及wrap_content和match_parent組合來構建復雜的布局,但是LinearLayout卻不允許你精準的控制它子view的關系,子view在LinearLayout中只能簡單一個接一個的排成行。如果你需要你的子view不只是簡簡單單的排成行的排列,更好的方法是使用RelativeLayout,它允許你指定你布局中控件與控件之間的關系,比如,你可以指定一個子view在左邊,另一個則在屏幕的右邊。
~~~
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Type here:"/>
<EditText
android:id="@+id/entry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/label"/>
<Button
android:id="@+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/entry"
android:layout_alignParentRight="true"
android:layout_marginLeft="10dp"
android:text="OK" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/ok"
android:layout_alignTop="@id/ok"
android:text="Cancel" />
</RelativeLayout>
~~~

圖2:QVGA(小尺寸屏幕)屏幕下截圖

圖3:WSVGA(大尺寸屏幕)屏幕下截圖
> 注意:盡管組件的尺寸發生了變化,但是它的子view之間的空間關系還是通過RelativeLayout.LayoutParams已經指定好了。
### 使用尺寸限定詞
(譯者注:這里的限定詞主要是指在編寫布局文件時,將布局文件放在加上類似large,sw600dp等這樣限定詞的文件夾中,以此來告訴系統根據屏幕選擇對應的布局文件,比如下面例子的layout-large文件夾)
從上一節的學習里程中,我們知道如何編寫靈活的布局或者相對布局,它們都能通過拉伸或者填充控件來適應不同的屏幕,但是它們卻不能為每個不同屏幕尺寸提供最好的用戶體驗。因此,你的應用不應該只是實現靈活的布局,同時也應該為不同的屏幕配置提供幾種不同的布局方式。你可以通過配置限定(configuration qualifiers)來做這件事情,它能在運行時根據你當前設備的配置(比如不同的屏幕尺寸設計了不同的布局)來選擇合適的布局資源。
比如,很多應用都為大屏幕實現了“兩個窗格”模式(應用可能在一個窗格中實現一個list的item,另外一個則實現list的content),平板和電視都是大到能在一個屏幕上適應兩個窗格,但是手機屏幕卻只能分別顯示。所以,如果你想實現這些布局,你就需要以下文件:
res/layout/main.xml.單個窗格(默認)布局:
~~~
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:id="@+id/headlines"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.HeadlinesFragment"
android:layout_width="match_parent" />
</LinearLayout>
~~~
res/layout-large/main.xml,兩個窗格布局:
~~~
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<fragment android:id="@+id/headlines"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.HeadlinesFragment"
android:layout_width="400dp"
android:layout_marginRight="10dp"/>
<fragment android:id="@+id/article"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.ArticleFragment"
android:layout_width="fill_parent" />
</LinearLayout>
~~~
注意第二個布局文件的目錄名字“large qualifier”,在大尺寸的設備屏幕時(比如7寸平板或者其他大屏幕的設備)就會選擇該布局文件,而其他比較小的設備則會選擇沒有限定詞的另一個布局(也就是第一個布局文件)。
### 使用最小寬度限定詞
在Android 3.2之前,開發者還有一個困難,那就是Android設備的“large”屏幕尺寸,其中包括Dell Streak(設備名稱),老版Galaxy Tab和一般的7寸平板,有很多的應用都想針對這些不同的設備(比如5和7寸的設備)定義不同的布局,但是這些設備都被定義為了large尺寸屏幕。也是因為這個,所以Android在3.2的時候開始使用最小寬度限定詞。
最小寬度限定詞允許你根據設備的最小寬度(dp單位)來指定不同布局。比如,傳統的7寸平板最小寬度為600dp,如果你希望你的UI能夠在這樣的屏幕上顯示兩個窗格(不是一個窗格顯示在小屏幕上),你可以使用上節中提到的使用同樣的兩個布局文件。不同的是,使用sw600來指定兩個方框的布局使用在最小寬度為600dp的設備上。
res/layout/main.xml,單個窗格(默認)布局:
~~~
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:id="@+id/headlines"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.HeadlinesFragment"
android:layout_width="match_parent" />
</LinearLayout>
~~~
res/layout-sw600dp/main.xml,兩個方框布局:
~~~
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<fragment android:id="@+id/headlines"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.HeadlinesFragment"
android:layout_width="400dp"
android:layout_marginRight="10dp"/>
<fragment android:id="@+id/article"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.ArticleFragment"
android:layout_width="fill_parent" />
</LinearLayout>
~~~
這樣意味著當你的設備的最小寬度等于600dp或者更大時,系統選擇layout-sw600dp/main.xml(兩個窗格)的布局,而小一點的屏幕則會選擇layout/main.xml(單個窗格)的布局。然而,在3.2之前的設備上,這樣做并不是很好的選擇。因為3.2之前還沒有將sw600dp作為一個限定詞出現,所以,你還是需要使用large限定詞來做。因此,你還是應該要有一個布局文件名為res/layout-large/main.xml,和res/layout-sw600dp/main.xml一樣。在下一節中,你將學到如何避免像這樣出現重復的布局文件。
### 使用布局別名
最小寬度限定詞只能在android3.2或者更高的版本上使用。因此,你還是需要使用抽象尺寸(small,normal,large,xlarge)來兼容以前的版本。比如,你想要將你的UI設計為在手機上只顯示一個方框的布局,而在7寸平板或電視,或者其他大屏幕設備上顯示多個方框的布局,你可能得提供這些文件:
-
res/layout/main.xml:單個窗格布局
-
res/layout-large:多個窗格布局
-
res/layout-sw600dp:多個窗格布局
最后兩個文件都是一樣的,因為其中一個將會適配Android3.2的設備,而另外一個則會適配其他Android低版本的平板或者電視。為了避免這些重復的文件(維護讓人感覺頭痛就是因為這個),你可以使用別名文件。比如,你可以定義如下布局:
- res/layout/main.xml,單個方框布局
- res/layout/main_twopans.xml,兩個方框布局
然后添加這兩個文件:
- res/values-large/layout.xml:
~~~
<resources>
<item name="main" type="layout">@layout/main_twopanes</item>
</resources>
~~~
- res/values-sw600dp/layout.xml:
~~~
<resources>
<item name="main" type="layout">@layout/main_twopanes</item>
</resources>
~~~
最后兩個文件擁有相同的內容,但它們并沒有真正意義上的定義布局。它們只是將main_twopanes設置成為了別名main,它們分別處在large和sw600dp選擇器中,所以它們能適配Android任何版本的平板和電視(在3.2之前平板和電視可以直接匹配large,而3.2或者以上的則匹配sw600dp)。
### 使用方向限定詞
有一些布局不管是在橫向還是縱向的屏幕配置中都能顯示的非常好,但是更多的時候,適當的調整一下會更好。在News Reader應用例子中,以下是布局在不同屏幕尺寸和方向的行為:
- 小屏幕,縱向:一個窗格加logo
- 小屏幕,橫向:一個窗格加logo
- 7寸平板,縱向:一個窗格加action bar
- 7寸平板,橫向:兩個寬窗格加action bar
- 10寸平板,縱向:兩個窄窗格加action bar
- 10寸平板,橫向:兩個寬窗格加action bar
- 電視,橫向:兩個寬窗格加action bar
這些每個布局都會在res/layout目錄下定義一個xml文件,如此,應用就能根據屏幕配置的變化根據別名匹配到對應的布局來適應屏幕。
res/layout/onepane.xml:
~~~
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:id="@+id/headlines"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.HeadlinesFragment"
android:layout_width="match_parent" />
</LinearLayout>
~~~
res/layout/onepane_with_bar.xml:
~~~
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:layout_width="match_parent"
android:id="@+id/linearLayout1"
android:gravity="center"
android:layout_height="50dp">
<ImageView android:id="@+id/imageView1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/logo"
android:paddingRight="30dp"
android:layout_gravity="left"
android:layout_weight="0" />
<View android:layout_height="wrap_content"
android:id="@+id/view1"
android:layout_width="wrap_content"
android:layout_weight="1" />
<Button android:id="@+id/categorybutton"
android:background="@drawable/button_bg"
android:layout_height="match_parent"
android:layout_weight="0"
android:layout_width="120dp"
style="@style/CategoryButtonStyle"/>
</LinearLayout>
<fragment android:id="@+id/headlines"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.HeadlinesFragment"
android:layout_width="match_parent" />
</LinearLayout>
~~~
res/layout/twopanes.xml:
~~~
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<fragment android:id="@+id/headlines"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.HeadlinesFragment"
android:layout_width="400dp"
android:layout_marginRight="10dp"/>
<fragment android:id="@+id/article"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.ArticleFragment"
android:layout_width="fill_parent" />
</LinearLayout>
~~~
res/layout/twopanes_narrow.xml:
~~~
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<fragment android:id="@+id/headlines"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.HeadlinesFragment"
android:layout_width="200dp"
android:layout_marginRight="10dp"/>
<fragment android:id="@+id/article"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.ArticleFragment"
android:layout_width="fill_parent" />
</LinearLayout>
~~~
現在所有可能的布局我們都已經定義了,唯一剩下的問題是使用方向限定詞來匹配對應的布局給屏幕。這時候,你就可以使用布局別名的功能了:
res/values/layouts.xml:
~~~
<resources>
<item name="main_layout" type="layout">@layout/onepane_with_bar</item>
<bool name="has_two_panes">false</bool>
</resources>
~~~
res/values-sw600dp-land/layouts.xml:
~~~
<resources>
<item name="main_layout" type="layout">@layout/twopanes</item>
<bool name="has_two_panes">true</bool>
</resources>
~~~
res/values-sw600dp-port/layouts.xml:
~~~
<resources>
<item name="main_layout" type="layout">@layout/onepane</item>
<bool name="has_two_panes">false</bool>
</resources>
~~~
res/values-large-land/layouts.xml:
~~~
<resources>
<item name="main_layout" type="layout">@layout/twopanes</item>
<bool name="has_two_panes">true</bool>
</resources>
~~~
res/values-large-port/layouts.xml:
~~~
<resources>
<item name="main_layout" type="layout">@layout/twopanes_narrow</item>
<bool name="has_two_panes">true</bool>
</resources>
~~~
### 使用.9.png圖片
支持不同的屏幕尺寸同時也意味著你的圖片資源也必須能兼容不同的屏幕尺寸。比如,一個button的背景圖片就必須要適應該button的各種形狀。
如果你在使用組件時可以改變圖片的大小,你很快就會發現這是一個不明確的選擇。因為運行的時候,圖片會被拉伸或者壓縮(這樣容易造成圖片失真)。避免這種情況的解決方案就是使用點9圖片,這是一種能夠指定哪些區域能夠或者不能夠拉伸的特殊png文件。
因此,在設計的圖片需要與組件一起變大變小時,一定要使用點9.若要將位圖轉換為點9,你可以用一個普通的圖片開始(下圖,是在4倍變焦情況下的圖片顯示)。
你可以通過sdk中的draw9patch程序(位于tools/directory目錄下)來畫點9圖片。通過沿左側和頂部邊框繪制像素來標記應該被拉伸的區域。也可以通過沿右側和底部邊界繪制像素來標記。就像下圖所示一樣:

請注意,上圖沿邊界的黑色像素。在頂部邊框和左邊框的那些表明圖像的可拉伸區域,右邊和底部邊框則表示內容應該放置的地方。
此外,注意.9.png這個格式,你也必須用這個格式,因為系統會檢測這是一個點9圖片而不是一個普通PNG圖片。
當你將這個應用到組件的背景的時候(通過設置android:background="@drawable/button"),android框架會自動正確的拉伸圖像以適應按鈕的大小,下圖就是各種尺寸中的顯示效果:

- 序言
- Android入門基礎:從這里開始
- 建立第一個App
- 創建Android項目
- 執行Android程序
- 建立簡單的用戶界面
- 啟動其他的Activity
- 添加ActionBar
- 建立ActionBar
- 添加Action按鈕
- 自定義ActionBar的風格
- ActionBar的覆蓋層疊
- 兼容不同的設備
- 適配不同的語言
- 適配不同的屏幕
- 適配不同的系統版本
- 管理Activity的生命周期
- 啟動與銷毀Activity
- 暫停與恢復Activity
- 停止與重啟Activity
- 重新創建Activity
- 使用Fragment建立動態的UI
- 創建一個Fragment
- 建立靈活動態的UI
- Fragments之間的交互
- 數據保存
- 保存到Preference
- 保存到文件
- 保存到數據庫
- 與其他應用的交互
- Intent的發送
- 接收Activity返回的結果
- Intent過濾
- Android分享操作
- 分享簡單的數據
- 給其他App發送簡單的數據
- 接收從其他App返回的數據
- 給ActionBar增加分享功能
- 分享文件
- 建立文件分享
- 分享文件
- 請求分享一個文件
- 獲取文件信息
- 使用NFC分享文件
- 發送文件給其他設備
- 接收其他設備的文件
- Android多媒體
- 管理音頻播放
- 控制音量與音頻播放
- 管理音頻焦點
- 兼容音頻輸出設備
- 拍照
- 簡單的拍照
- 簡單的錄像
- 控制相機硬件
- 打印
- 打印照片
- 打印HTML文檔
- 打印自定義文檔
- Android圖像與動畫
- 高效顯示Bitmap
- 高效加載大圖
- 非UI線程處理Bitmap
- 緩存Bitmap
- 管理Bitmap的內存
- 在UI上顯示Bitmap
- 使用OpenGL ES顯示圖像
- 建立OpenGL ES的環境
- 定義Shapes
- 繪制Shapes
- 運用投影與相機視圖
- 添加移動
- 響應觸摸事件
- 添加動畫
- View間漸變
- 使用ViewPager實現屏幕側滑
- 展示卡片翻轉動畫
- 縮放View
- 布局變更動畫
- Android網絡連接與云服務
- 無線連接設備
- 使得網絡服務可發現
- 使用WiFi建立P2P連接
- 使用WiFi P2P服務
- 執行網絡操作
- 連接到網絡
- 管理網絡
- 解析XML數據
- 高效下載
- 為網絡訪問更加高效而優化下載
- 最小化更新操作的影響
- 避免下載多余的數據
- 根據網絡類型改變下載模式
- 云同步
- 使用備份API
- 使用Google Cloud Messaging
- 解決云同步的保存沖突
- 使用Sync Adapter傳輸數據
- 創建Stub授權器
- 創建Stub Content Provider
- 創建Sync Adpater
- 執行Sync Adpater
- 使用Volley執行網絡數據傳輸
- 發送簡單的網絡請求
- 建立請求隊列
- 創建標準的網絡請求
- 實現自定義的網絡請求
- Android聯系人與位置信息
- Android聯系人信息
- 獲取聯系人列表
- 獲取聯系人詳情
- 使用Intents修改聯系人信息
- 顯示聯系人頭像
- Android位置信息
- 獲取最后可知位置
- 獲取位置更新
- 顯示位置地址
- 創建和監視地理圍欄
- Android可穿戴應用
- 賦予Notification可穿戴特性
- 創建Notification
- 在Notifcation中接收語音輸入
- 為Notification添加顯示頁面
- 以Stack的方式顯示Notifications
- 創建可穿戴的應用
- 創建并運行可穿戴應用
- 創建自定義的布局
- 添加語音功能
- 打包可穿戴應用
- 通過藍牙進行調試
- 創建自定義的UI
- 定義Layouts
- 創建Cards
- 創建Lists
- 創建2D-Picker
- 創建確認界面
- 退出全屏的Activity
- 發送并同步數據
- 訪問可穿戴數據層
- 同步數據單元
- 傳輸資源
- 發送與接收消息
- 處理數據層的事件
- Android TV應用
- 創建TV應用
- 創建TV應用的第一步
- 處理TV硬件部分
- 創建TV的布局文件
- 創建TV的導航欄
- 創建TV播放應用
- 創建目錄瀏覽器
- 提供一個Card視圖
- 創建詳情頁
- 顯示正在播放卡片
- 幫助用戶在TV上探索內容
- TV上的推薦內容
- 使得TV App能夠被搜索
- 使用TV應用進行搜索
- 創建TV游戲應用
- 創建TV直播應用
- TV Apps Checklist
- Android企業級應用
- Ensuring Compatibility with Managed Profiles
- Implementing App Restrictions
- Building a Work Policy Controller
- Android交互設計
- 設計高效的導航
- 規劃屏幕界面與他們之間的關系
- 為多種大小的屏幕進行規劃
- 提供向下和橫向導航
- 提供向上和歷史導航
- 綜合:設計樣例 App
- 實現高效的導航
- 使用Tabs創建Swipe視圖
- 創建抽屜導航
- 提供向上的導航
- 提供向后的導航
- 實現向下的導航
- 通知提示用戶
- 建立Notification
- 當啟動Activity時保留導航
- 更新Notification
- 使用BigView風格
- 顯示Notification進度
- 增加搜索功能
- 建立搜索界面
- 保存并搜索數據
- 保持向下兼容
- 使得你的App內容可被Google搜索
- 為App內容開啟深度鏈接
- 為索引指定App內容
- Android界面設計
- 為多屏幕設計
- 兼容不同的屏幕大小
- 兼容不同的屏幕密度
- 實現可適應的UI
- 創建自定義View
- 創建自定義的View類
- 實現自定義View的繪制
- 使得View可交互
- 優化自定義View
- 創建向后兼容的UI
- 抽象新的APIs
- 代理至新的APIs
- 使用舊的APIs實現新API的效果
- 使用版本敏感的組件
- 實現輔助功能
- 開發輔助程序
- 開發輔助服務
- 管理系統UI
- 淡化系統Bar
- 隱藏系統Bar
- 隱藏導航Bar
- 全屏沉浸式應用
- 響應UI可見性的變化
- 創建使用Material Design的應用
- 開始使用Material Design
- 使用Material的主題
- 創建Lists與Cards
- 定義Shadows與Clipping視圖
- 使用Drawables
- 自定義動畫
- 維護兼容性
- Android用戶輸入
- 使用觸摸手勢
- 檢測常用的手勢
- 跟蹤手勢移動
- Scroll手勢動畫
- 處理多觸摸手勢
- 拖拽與縮放
- 管理ViewGroup中的觸摸事件
- 處理鍵盤輸入
- 指定輸入法類型
- 處理輸入法可見性
- 兼容鍵盤導航
- 處理按鍵動作
- 兼容游戲控制器
- 處理控制器輸入動作
- 支持不同的Android系統版本
- 支持多個控制器
- Android后臺任務
- 在IntentService中執行后臺任務
- 創建IntentService
- 發送工作任務到IntentService
- 報告后臺任務執行狀態
- 使用CursorLoader在后臺加載數據
- 使用CursorLoader執行查詢任務
- 處理查詢的結果
- 管理設備的喚醒狀態
- 保持設備的喚醒
- 制定重復定時的任務
- Android性能優化
- 管理應用的內存
- 代碼性能優化建議
- 提升Layout的性能
- 優化layout的層級
- 使用include標簽重用layouts
- 按需加載視圖
- 使得ListView滑動順暢
- 優化電池壽命
- 監測電量與充電狀態
- 判斷與監測Docking狀態
- 判斷與監測網絡連接狀態
- 根據需要操作Broadcast接受者
- 多線程操作
- 在一個線程中執行一段特定的代碼
- 為多線程創建線程池
- 啟動與停止線程池中的線程
- 與UI線程通信
- 避免出現程序無響應ANR
- JNI使用指南
- 優化多核處理器(SMP)下的Android程序
- Android安全與隱私
- Security Tips
- 使用HTTPS與SSL
- 為防止SSL漏洞而更新Security
- 使用設備管理條例增強安全性
- Android測試程序
- 測試你的Activity
- 建立測試環境
- 創建與執行測試用例
- 測試UI組件
- 創建單元測試
- 創建功能測試
- 術語表