最近打算好好看看android的官方文檔,Training
的已經(jīng)看過(guò)了,打算看下Guide
指導(dǎo)文檔,這個(gè)比Training
會(huì)介紹得更加詳細(xì)。
谷歌的官網(wǎng)因?yàn)楸粔Γ赃@里介紹一個(gè)國(guó)內(nèi)的鏡像Android 6.0官網(wǎng),本篇文章是第一篇文章,地址是Application Fundamentals
主要是翻譯Guide
文檔的內(nèi)容,但不一定會(huì)逐句翻譯,因?yàn)橛⒄Z(yǔ)水平問(wèn)題,可能會(huì)有選擇的翻譯一些自己認(rèn)為比較重要的內(nèi)容,但是介紹的知識(shí)點(diǎn)會(huì)盡可能保證都翻譯到。
應(yīng)用基礎(chǔ)(Application Fundamentals)
Android的app是使用Java語(yǔ)言編寫的。Android SDK工具是用來(lái)將你寫的代碼以及一些數(shù)據(jù)和資源文件,編譯成一個(gè)APK,APK是一個(gè)android的包,是一個(gè)后綴名為.apk
的歸檔文件(archive file)。一個(gè)APK文件包含了一個(gè)android app的所有內(nèi)容,也是使用android系統(tǒng)的設(shè)備用來(lái)安裝app的文件。
一旦在一個(gè)設(shè)備上安裝了,每個(gè) android app 都是運(yùn)行在自己的安全沙箱中:
- android的操作系統(tǒng)是一個(gè)多用戶的Linux系統(tǒng),每個(gè)app是一個(gè)不同的用戶
- 默認(rèn)情況下,系統(tǒng)會(huì)給每個(gè)app分配一個(gè)獨(dú)立的Linux用戶ID(這個(gè)ID只是系統(tǒng)使用,app是不知道這個(gè)ID的)。系統(tǒng)會(huì)給一個(gè)app中所有文件都設(shè)置了權(quán)限,只有分配給這個(gè)app的用戶ID才可以使用這些文件
- 每個(gè)進(jìn)程都有自己的虛擬機(jī)(virtual machine,VM),因此每個(gè)app都是相互隔離地運(yùn)行自己的代碼的
- 默認(rèn)情況,每個(gè)app都是運(yùn)行在自己的Linux進(jìn)程。當(dāng)app的組件需要被執(zhí)行時(shí),Android會(huì)開始其進(jìn)程,而在其不用執(zhí)行或者系統(tǒng)必須給其他應(yīng)用分配內(nèi)存(recover memory)時(shí)會(huì)關(guān)掉這個(gè)進(jìn)程。
通過(guò)上述方式,Android系統(tǒng)實(shí)現(xiàn)了最少特權(quán)原則(the principle of least privilege)。也就是對(duì)于每個(gè)app,默認(rèn)情況,它只可以使用用于完成其工作的組件。這就創(chuàng)造了一個(gè)非常安全的環(huán)境,每個(gè)app都無(wú)法獲取它沒(méi)有得到權(quán)限的系統(tǒng)功能或服務(wù)。
然而,對(duì)每個(gè)app,還是有方法可以跟其他app分享數(shù)據(jù)以及使用系統(tǒng)的服務(wù)的:
- 給兩個(gè)app分享同一個(gè)Linux的用戶ID是有可能的,在這種情況下它們是可以使用對(duì)方的文件。出于節(jié)省系統(tǒng)資源的考慮,擁有一樣用戶ID的apps會(huì)分配到同一個(gè)Linux進(jìn)程中,并且共享同一個(gè)VM(這些apps都必須簽署同樣的證書)
- 一個(gè)應(yīng)用是可以要求獲取使用設(shè)備數(shù)據(jù)的權(quán)限,如用戶的聯(lián)系人,短信,SD卡,照相機(jī),藍(lán)牙等等。所有的應(yīng)用權(quán)限都必須在安裝的時(shí)候得到用戶的同意。
以上內(nèi)容包含了基本的關(guān)于一個(gè)android應(yīng)用如何存在于系統(tǒng)中,本文接下來(lái)的將介紹以下內(nèi)容:
- 定義app中的核心框架組件
-
mainfest
文件,用于聲明組件以及要求設(shè)備功能 - 跟app代碼分開的資源文件,用于讓你的應(yīng)用可以在面對(duì)多種設(shè)備配置時(shí)優(yōu)雅地優(yōu)化其行為
1.應(yīng)用組件(App Components)
應(yīng)用組件是一個(gè)Android應(yīng)用的基本建筑基石。每個(gè)組件是一個(gè)系統(tǒng)可以進(jìn)入應(yīng)用的不同點(diǎn)。但不是所有的組件是用戶實(shí)際的入口點(diǎn),其中一些需要相互依賴,但每一個(gè)都是作為一個(gè)實(shí)體存在并且扮演一個(gè)特殊的角色——每一個(gè)組件都是一個(gè)幫助開發(fā)者定義其應(yīng)用整體行為的基石。
總共有4種不同類型的應(yīng)用組件。每一種類型都是用于一個(gè)明顯的用途,并且都有一個(gè)清楚的定義了其如何創(chuàng)建和摧毀的生命周期。
Activities
一個(gè)活動(dòng)表示用戶界面上一個(gè)單獨(dú)的屏幕。例如,在一個(gè)電子郵件的應(yīng)用中會(huì)有一個(gè)展示新郵件列表的活動(dòng),一個(gè)活動(dòng)是用于寫信,以及一個(gè)讀取郵件內(nèi)容的活動(dòng)。盡管在這個(gè)應(yīng)用中這些活動(dòng)一起運(yùn)作形成了一個(gè)有凝聚力的用戶體驗(yàn),但每個(gè)活動(dòng)都是相互獨(dú)立的。同樣地,另一個(gè)不同的應(yīng)用是可以打開這些活動(dòng)中的任何一個(gè)(在獲得該電子郵件應(yīng)用的允許的前提下)。例如,一個(gè)照相應(yīng)用可以打開這個(gè)電子郵件應(yīng)用中的寫信的活動(dòng),以便于用戶可以分享一張圖片。
Services
一個(gè)服務(wù)是一個(gè)運(yùn)行在后臺(tái),執(zhí)行長(zhǎng)時(shí)間運(yùn)算或者執(zhí)行遠(yuǎn)程進(jìn)程的工作的組件。服務(wù)是沒(méi)有用戶界面的。例如,當(dāng)用戶在使用其他應(yīng)用的時(shí)候,一個(gè)服務(wù)正在后臺(tái)播放音樂(lè),或者它是在通過(guò)網(wǎng)絡(luò)獲取一些數(shù)據(jù)但沒(méi)有阻礙用戶與一個(gè)活動(dòng)界面進(jìn)行交互。其他的組件,如一個(gè)活動(dòng),可以開啟服務(wù)并讓它運(yùn)行,或者綁定這個(gè)服務(wù)來(lái)與它進(jìn)行交互。
Content providers
一個(gè)內(nèi)容提供器是管理一個(gè)用于分享的應(yīng)用數(shù)據(jù)集。開發(fā)者可以通過(guò)文件系統(tǒng),一個(gè)SQLite數(shù)據(jù)庫(kù),網(wǎng)絡(luò),或其他固定的應(yīng)用可以訪問(wèn)的存儲(chǔ)位置來(lái)保存數(shù)據(jù)。通過(guò)內(nèi)容提供器,其他的應(yīng)用可以查詢甚至修改數(shù)據(jù)(在這個(gè)內(nèi)容提供器允許前提下)。例如,Android系統(tǒng)提供了一個(gè)管理用戶聯(lián)系人信息的內(nèi)容提供器。正因?yàn)槿绱耍魏我粋€(gè)應(yīng)用在有合法的權(quán)限下都可以查詢這個(gè)內(nèi)容提供器(如ContactsContract.Data
)來(lái)讀寫一個(gè)特定的人的信息。
Broadcast receivers
一個(gè)廣播接收器是一個(gè)用于響應(yīng)系統(tǒng)全局廣播通知的組件。很多廣播都是起源于系統(tǒng)——例如,一個(gè)廣播通知屏幕要關(guān)閉,電量低,或者截屏。應(yīng)用也可以初始化廣播——例如,讓其他應(yīng)用知道有些數(shù)據(jù)被下載到設(shè)備中并且可以提供給它們使用。盡管廣播接收器沒(méi)有顯示一個(gè)用戶界面,但是它們可以創(chuàng)建一條狀態(tài)欄的通知來(lái)提醒用戶有一個(gè)廣播事件發(fā)生了。但更普遍的情況是,一個(gè)廣播接收器僅僅是一個(gè)通向其他組件的“門(gateway)”,并且一般只做很少量的工作,例如,廣播接收器可能就是開啟一個(gè)基于廣播事件的執(zhí)行一些任務(wù)的服務(wù)。
2.Activating Components
在4種組件類型中有三種--活動(dòng)、服務(wù)和廣播接收器--都是通過(guò)一個(gè)叫做intent
的異步信息啟動(dòng)的。Intents可以在運(yùn)行時(shí)將獨(dú)立的組件綁定在一起(可以將它們看做是需要從其他組件中要求一個(gè)action
的信使),無(wú)論這個(gè)組件是否屬于你的應(yīng)用。
通過(guò)使用一個(gè)Intent
對(duì)象可以創(chuàng)建一個(gè)intent
,它可以使用一個(gè)信息來(lái)啟動(dòng)一個(gè)特定的組件或者一類組件,即intent
是分為顯式的和隱式的。
對(duì)于活動(dòng)和服務(wù),一個(gè)intent定義了需要執(zhí)行的action
(如發(fā)送或者查看),有可能還會(huì)特定數(shù)據(jù)的URI
,比如需要打開一個(gè)網(wǎng)頁(yè)的時(shí)候,這個(gè)URI
就是網(wǎng)頁(yè)的網(wǎng)址了。在某些情況下,活動(dòng)在使用一個(gè)intent后,還可以接受返回的結(jié)果,這個(gè)結(jié)果也是通過(guò)Intent
返回的。
對(duì)于廣播接收器,intent只是簡(jiǎn)單定義了正在廣播的通知。
對(duì)于內(nèi)容提供器,它是由ContentResolver
來(lái)啟動(dòng)的。它可以處理跟內(nèi)容提供器所有的直接事務(wù)。
對(duì)不同組件有不同的開啟方法:
- 對(duì)于活動(dòng),可以傳遞一個(gè)
Intent
給startActivity()
或者startActivityForResult()
(當(dāng)需要開啟的活動(dòng)返回一個(gè)結(jié)果時(shí)); - 對(duì)于服務(wù),傳遞一個(gè)
Intent
給startService()
方法來(lái)開啟服務(wù),綁定服務(wù)則是傳遞給bindService()
; - 初始化一個(gè)廣播可以通過(guò)傳遞
Intent
給如sendBroadcast()
,sendOrderedBroadcast()
,或者sendStickyBroadcast()
; - 通過(guò)調(diào)用
ContentResolver
的query()
可以實(shí)現(xiàn)對(duì)內(nèi)容提供器的查詢。
3. The Manifest File
所有的組件都必須在一個(gè)文件——AndroidManifest.xml
中聲明,Android 系統(tǒng)才能使用它,這個(gè)文件必須是在應(yīng)用項(xiàng)目文件的根目錄中。
除了用于聲明組件,它還有以下這些功能:
- 聲明應(yīng)用所需要的用戶權(quán)限,比如網(wǎng)絡(luò)連接或者是讀取用戶的聯(lián)系人;
- 聲明該應(yīng)用要求的最低 API Level,(在Android Studio中這個(gè)功能是放在
build.gradle
中了) - 聲明應(yīng)用需要用到或者要求的硬件和軟件的功能特性,比如照相機(jī),藍(lán)牙,或者是一個(gè)多點(diǎn)觸摸的屏幕
- 應(yīng)用需要鏈接到的 API 庫(kù),比如 Google Maps library
- 等等
聲明組件
manifest
的主要任務(wù)是聲明組件,比如,一個(gè)聲明活動(dòng)的例子如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:icon="@drawable/app_icon.png" ... >
<activity android:name="com.example.project.ExampleActivity"
android:label="@string/example_label" ... >
</activity>
...
</application>
</manifest>
沒(méi)有在這個(gè)文件聲明的組件是不可以使用的,除了廣播接收器外。
廣播接收器即可以在該文件中聲明,也可以在代碼中動(dòng)態(tài)地創(chuàng)建,并使用registerReceiver()
方法在進(jìn)行注冊(cè)。
聲明組件的功能
Intent
的真正作用體現(xiàn)在使用隱式intent上,這種intent簡(jiǎn)單描述了需要執(zhí)行的行為類型,有時(shí)還會(huì)說(shuō)明需要使用的數(shù)據(jù),然后系統(tǒng)就會(huì)尋找可以執(zhí)行這種行為的組件并啟動(dòng)它,而如果有多種組件,那么用戶可以選擇使用哪一個(gè)。
通過(guò)在AndroidManifest.xml
聲明組件時(shí),使用一個(gè)<intent-filter>
可以聲明該組件的功能,也就是其能執(zhí)行的行為。
下面是一個(gè)郵件應(yīng)用中用戶寫信的一個(gè)活動(dòng)的聲明例子:
<manifest ... >
...
<application ... >
<activity android:name="com.example.project.ComposeEmailActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<data android:type="*/*" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
這個(gè)例子中的活動(dòng)可以響應(yīng)需要ACTION_SEND
的intent
聲明應(yīng)用的必要條件
由于Android的設(shè)備非常多,但不是所有的設(shè)備都擁有同樣的功能和特性,在AndroidManifest.xml
文件中聲明應(yīng)用所需要的硬件和軟件功能和特性是有必要的。
不過(guò)大部分這些聲明都只是信息,系統(tǒng)也不會(huì)讀取它們,但對(duì)于如 Google Play 會(huì)讀取它們?nèi)缓蠼o用戶進(jìn)行過(guò)濾。
例如,你的應(yīng)用需要使用照相功能并且使用 Android 2.1(API Level 7)的 API,應(yīng)該如下所示:
<manifest ... >
<uses-feature android:name="android.hardware.camera.any"
android:required="true" />
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="19" />
...
</manifest>
這樣,當(dāng)不具備以上要求的設(shè)備是無(wú)法從 Google Play 上安裝的。當(dāng)然上述的android:required
也可以設(shè)置為false
,這表示你的應(yīng)用使用照相功能,但并不要求設(shè)備擁有這個(gè)功能,所以在運(yùn)行的時(shí)候會(huì)檢查設(shè)備是否有照相機(jī),并且會(huì)在適當(dāng)?shù)臅r(shí)候關(guān)閉這個(gè)功能。
4. 應(yīng)用資源
一個(gè)android應(yīng)用除了代碼外,還有一些其他的資源,比如圖片,音頻文件,以及任何與應(yīng)用的視覺(jué)展示有關(guān)的東西。使用應(yīng)用資源可以在不修改代碼的情況下升級(jí)應(yīng)用的不同功能特性,并且可以使應(yīng)用適配不同的設(shè)備配置(如不同的語(yǔ)言和屏幕尺寸)。
對(duì)每個(gè)在項(xiàng)目中使用到的資源,SDK 編譯工具都會(huì)定義一個(gè)獨(dú)一無(wú)二的整型 ID,這個(gè)可以在代碼中或者 XML 中用來(lái)引用這個(gè)資源。
使用應(yīng)用資源可以有利于適配不同的設(shè)備配置,比如對(duì)于在 XML 中使用字符串,可以將字符串翻譯成其他語(yǔ)言并保存在不同的文件,并且對(duì)該文件名字使用一個(gè)限定符(如res/values-fr/
是用于法語(yǔ)的字符串)。
Android提供了很多不同的限定符,它是一個(gè)短字符串用于放在資源文件名字中。例如,對(duì)于布局,通常需要?jiǎng)?chuàng)建不同的布局文件,因?yàn)樵O(shè)備的屏幕方向和尺寸。當(dāng)屏幕是垂直的(portrait
)或者是水平的(landscape
),可以定義兩個(gè)不同的布局文件來(lái)對(duì)應(yīng)這兩種情況,而系統(tǒng)會(huì)根據(jù)當(dāng)前設(shè)備的方向來(lái)自動(dòng)使用合適的布局。
5. 總結(jié)
第一篇簡(jiǎn)單介紹了 android 的開發(fā)語(yǔ)言是 Java
,這個(gè)是最基礎(chǔ)的,也是學(xué)習(xí)android首先需要掌握的基礎(chǔ)語(yǔ)言,而且我也認(rèn)為想要在android這條道路上走得更遠(yuǎn),Java還不能只是了解,還必須要好好掌握好,畢竟到時(shí)如果要閱讀源碼,讀的可以都是用java寫的代碼,所以重新好好系統(tǒng)學(xué)學(xué)java也是一個(gè)近期的計(jì)劃。當(dāng)然,最近看到有說(shuō)可以使用其他語(yǔ)言來(lái)寫android,比如kotlin
這門語(yǔ)言,還有就是說(shuō)swift
要支持 Android了,不過(guò)這個(gè)目前只是 NDK
支持而已。
其次還介紹了 android 的四大組件, 目前用得比較多的當(dāng)然還是 Activity
了,其他三個(gè)組件用得比較少,甚至還沒(méi)怎么使用過(guò),不過(guò)這也是目前開發(fā)的經(jīng)驗(yàn)比較少,做過(guò)的項(xiàng)目不多。
然后就是AndroidManifest
文件,用來(lái)注冊(cè)四大組件,聲明應(yīng)用需要的權(quán)限和硬件必須具備的功能等,還有就是說(shuō)明了 Android 中除了純 Java 代碼外,還有其他資源文件,包括圖片,布局文件等,這里需要根據(jù)設(shè)備的屏幕大小,分辨率,屏幕方向等分別設(shè)置對(duì)應(yīng)的資源文件。
第一次寫文章,主要是翻譯自官方文檔,因?yàn)橛⒄Z(yǔ)水平和表達(dá)水平不是很好,所以有翻譯錯(cuò)誤和表達(dá)不好的地方都?xì)g迎提出來(lái)。