本文介紹的是android基礎(chǔ)的相關(guān)概念,基本都是來自android開發(fā)者網(wǎng)站以及個(gè)人的理解
android最基礎(chǔ)的兩個(gè)優(yōu)點(diǎn):
1、應(yīng)用提供多個(gè)入口點(diǎn)
2、應(yīng)用可適應(yīng)不同的設(shè)備
Q:經(jīng)常聽到android的優(yōu)點(diǎn)之一是:提供多個(gè)入口點(diǎn)(entry point)去啟動(dòng)應(yīng)用程序APP;怎么理解這句話呢?
A:安卓APP是由多個(gè)相對(duì)獨(dú)立的組件(如activity,service,broadcast receiver等)組成的,這些組件都可以作為一個(gè)獨(dú)立的入口點(diǎn)去啟動(dòng)該應(yīng)用運(yùn)行起來。典型例子是:你在應(yīng)用A中想要開啟拍照功能,可以直接通過接口去啟動(dòng)系統(tǒng)自帶的“相機(jī)”,然后去拍照。并不用退出桌面后通過點(diǎn)擊“相機(jī)”圖標(biāo)去拍照。所以安卓的入口點(diǎn)不單單是桌面上的“icon圖標(biāo)”。而是桌面上的 “icon圖標(biāo)” + “組成該APP的相關(guān)組件”
Q:android系統(tǒng)的另一個(gè)優(yōu)點(diǎn)是:支持App層方便的兼容不同的設(shè)備;怎么理解這句話呢?
A:因?yàn)閍ndroid系統(tǒng)的初衷是讓所有的移動(dòng)設(shè)備上都能安裝android系統(tǒng),運(yùn)行由android系統(tǒng)開發(fā)的App,所以android系統(tǒng)在設(shè)計(jì)之初就考慮到了支持不同的設(shè)備類型,并由此在系統(tǒng)層設(shè)計(jì)了一整套資源匹配框架。具體為:系統(tǒng)FrameWork層支持APP根據(jù)設(shè)備的不同特性存放不同的資源,APP層只需要根據(jù)相關(guān)規(guī)則(如文件名稱,文件存放路徑等)供對(duì)應(yīng)的資源(如匹配中文,需要將string.xml文件放在res/values-zh-rCN/路徑下)。然后在APP運(yùn)行的時(shí)候,系統(tǒng)層會(huì)根據(jù)設(shè)備相關(guān)參數(shù)(如屏幕分辨率,地區(qū)等)去選擇最佳的資源適配該設(shè)備。
Q:activity上的View是怎么顯示出來的呢?
A:android activity的界面是通過"容器+元件"組成的
容器:即ViewGroup,是存放其他子View的一個(gè)容器。如LinearLayout,FrameLayout等等
元件:即子View,用于顯示內(nèi)容的具體控件。如TextView,ImageView等等

Q:在app中的layout布局文件中,通過屬性android:onClick為控件增加"單擊"時(shí)回調(diào)的方法有什么具體的要求嗎?
A:有條件限制的;對(duì)于android:onClick屬性回調(diào)的方法,該方法必須滿足:
(1)是public訪問修飾符修飾的
(2)方法返回值必須是void
(3)View是唯一的參數(shù),該View實(shí)際上就是發(fā)生"單擊"事件的View
如:
public void sendMsg(View v){
//該方法就能被用到android:onClick屬性中
}
具體回調(diào)的源碼,需要進(jìn)一步分析
Q:怎么初步理解android的intent?
A:intent是android系統(tǒng)中相互獨(dú)立的組件之間提供運(yùn)行時(shí)綁定的對(duì)象,該對(duì)象定義了特定的消息去告知系統(tǒng),用于激活對(duì)應(yīng)的組件。眾所周知,android系統(tǒng)中的4大組件(activity,broadcast receiver, service, content provider)是相互獨(dú)立的,而他們之間的聯(lián)系就需要通過intent作為一個(gè)中間信使。這樣,使得android在app層級(jí)組件之間的耦合性降到最低,這也是android系統(tǒng)的優(yōu)點(diǎn)之一。
注意:android四大組件中,只有三種(activity,service,broadcast receiver)是由為intent的異步消息去啟動(dòng)激活的。即通過發(fā)送intent(里面攜帶一條擁有特定action,category等信息)告知系統(tǒng),讓系統(tǒng)去激活對(duì)應(yīng)的組件。而Content Provider并不是通過intent方式去激活的
Q:怎么理解4大組件之間相互獨(dú)立呢?
A:即假設(shè)有activityA 和 activityB,這兩個(gè)activity之間不管缺少了activityA或者缺少了activityB,另一個(gè)activity都能正常運(yùn)行。這就是組件之間的相互獨(dú)立性
Q:acitivity有什么具體的作用?
A:activity的具體作用如下:
(1)展示信息給用戶
(2)監(jiān)聽并響應(yīng)用戶的操作
(3)讓系統(tǒng)知道當(dāng)前哪個(gè)app的進(jìn)程優(yōu)先級(jí)最高,這樣在內(nèi)存緊張的時(shí)候,最后kill在前臺(tái)展示activity的app進(jìn)程
(4)提供了一種交互方式,讓用戶流在app之間流通。最典型的例子就是分享圖片,拍照,去調(diào)用別的app中的activity,實(shí)現(xiàn)用戶流的流轉(zhuǎn)。
Q:service有什么具體的作用?
A:service的具體作用如下:
(1)沒有UI界面,在后臺(tái)長時(shí)間執(zhí)行一些耗時(shí)\非耗時(shí)操作,如訪問網(wǎng)絡(luò)數(shù)據(jù)等
(2)后臺(tái)運(yùn)行的服務(wù)類型影響著系統(tǒng)對(duì)該后臺(tái)服務(wù)的app的管理情況;
如在后臺(tái)播放音樂:由于音頻交互是用戶可感知的,僅次于activity的UI交互。所以該服務(wù)所對(duì)應(yīng)的app的優(yōu)先級(jí)更高,在內(nèi)存緊張的時(shí)候,不會(huì)輕易kill該app去釋放內(nèi)存;
如在后臺(tái)下載視頻數(shù)據(jù):該過程對(duì)用戶來說是非實(shí)時(shí)的,所以在內(nèi)存緊張的時(shí)候,可以先kill該服務(wù)對(duì)應(yīng)的進(jìn)程,后面內(nèi)存富足之后再啟動(dòng)該服務(wù)繼續(xù)下載視頻數(shù)據(jù)。
對(duì)于android系統(tǒng)來說,kill app的優(yōu)先級(jí)管理策略的核心依據(jù)是:該app和用戶的交互狀態(tài)。如果當(dāng)前處于強(qiáng)交互狀態(tài),那么優(yōu)先級(jí)就更高,更不容易被kill;如果處于弱交互甚至無交互狀態(tài),那么優(yōu)先級(jí)就低,內(nèi)存不足的時(shí)候會(huì)優(yōu)先kill這些進(jìn)程
(3)可以通過綁定服務(wù)來提高該服務(wù)的優(yōu)先級(jí)。如可以將一個(gè)前臺(tái)Activity A綁定到服務(wù)B上,那么會(huì)大幅提高該服務(wù)的優(yōu)先級(jí)至Activity A相等的優(yōu)先級(jí);因?yàn)榻壎ǚ?wù)相當(dāng)于告知系統(tǒng),該前臺(tái)Activity A的正常運(yùn)行需要用到服務(wù)B。所以為了保證前臺(tái)該Activity A的正常運(yùn)行以及用戶體驗(yàn),在內(nèi)存緊張的時(shí)候,也不會(huì)優(yōu)先kill該服務(wù)B。
Q:broadcast有什么具體的作用?
A:broadcast的具體作用如下:
(1)系統(tǒng)能夠在常規(guī)用戶流之外將事件傳遞給應(yīng)用程序的組件,使應(yīng)用程序能夠響應(yīng)系統(tǒng)范圍的廣播。常規(guī)用戶流:應(yīng)該是指用戶操作觸發(fā)的事件,是常規(guī)的交互方式。如在App A中通過點(diǎn)擊拍照按鈕,會(huì)去啟動(dòng)系統(tǒng)相機(jī)App B,這是最常規(guī),也是最重要的交互方式,直接去啟動(dòng)對(duì)應(yīng)的activity去傳遞事件。而廣播接收器是以另一種方式進(jìn)行交互,通過廣播,將常規(guī)用戶操作之外的事件(尤其是系統(tǒng)的相關(guān)事件,如電源不足事件等等)傳遞給app,讓app去做對(duì)應(yīng)的處理
(2)系統(tǒng)能夠?qū)V播傳遞給所有的app,甚至是沒有處在運(yùn)行狀態(tài)的app(只需要靜態(tài)注冊(cè)對(duì)應(yīng)的broadcast recevier就可以)
Q:啟動(dòng)android 組件activity,service,broadcast receiver的方式有哪些?
A:具體的啟動(dòng)方式有如下這些:
(1)activity啟動(dòng)方式:startActivity() 或 startActivityForResult(),參數(shù)是intent
(2)service啟動(dòng)方式:android 5.0之前,是 startService() 或 bindService(),參數(shù)是intent。android 5.0之后,通過JobScheduler類來調(diào)度操作
(3)broadcast receiver啟動(dòng)方式:通過 sendBroadcast()、sendOrderedBroadcast() 或 sendStickyBroadcast() 等方法發(fā)送廣播,讓系統(tǒng)去啟動(dòng)對(duì)應(yīng)的broadcast receiver處理,參數(shù)是intent
Q:android系統(tǒng)是基于Linux系統(tǒng)開發(fā)的嗎?為什么要基于Linux系統(tǒng)?
A:安卓系統(tǒng)是基于Linux內(nèi)核開發(fā)而成的,所以可以說,安卓系統(tǒng)本質(zhì)上就是一個(gè)Linux操作系統(tǒng)。因此,android系統(tǒng)擁有Linux操作系統(tǒng)的絕大多數(shù)特性。而Linux最大的特性就是:多用戶,多任務(wù),多cpu,多線程。android系統(tǒng)完美的繼承了這些優(yōu)點(diǎn)。所以android系統(tǒng)的特性為:
1、Android 操作系統(tǒng)是一種多用戶Linux系統(tǒng),其中的每個(gè)應(yīng)用都是一個(gè)不同的用戶。就像ubuntu系統(tǒng)可以創(chuàng)建多個(gè)用戶一樣,如linsiyan,junlinge等用戶帳號(hào)。而android系統(tǒng)是將每一個(gè)應(yīng)用當(dāng)作一個(gè)用戶,這樣就完美的繼承了Linux為多用戶設(shè)計(jì)的安全機(jī)制(訪問權(quán)限等等),使得每一個(gè)應(yīng)用在運(yùn)行時(shí)能最大程度保證安全性,獨(dú)立性,不受其他應(yīng)用干擾;
2、默認(rèn)情況下,系統(tǒng)會(huì)為每個(gè)應(yīng)用分配一個(gè)唯一的Linux用戶ID(該ID僅由系統(tǒng)使用,應(yīng)用并不知曉)。系統(tǒng)會(huì)為應(yīng)用中的所有文件設(shè)置權(quán)限,使得只有分配給該應(yīng)用的用戶ID才能訪問這些文件;這個(gè)就是Linux的多用戶安全機(jī)制。這里會(huì)有一個(gè)疑問:為什么說是默認(rèn)情況下呢?難道還有非默認(rèn)情況?
是的,非默認(rèn)情況就是android系統(tǒng)支持不同的應(yīng)用共享同一個(gè) User id。通過這種方式,可以使不同應(yīng)用之間互相訪問數(shù)據(jù)等
3、每個(gè)進(jìn)程(Process)都擁有自己的虛擬機(jī)(VM),因此應(yīng)用代碼獨(dú)立于其他應(yīng)用而運(yùn)行。這也是Linux系統(tǒng)支持多進(jìn)程的優(yōu)點(diǎn)
4、默認(rèn)情況下,每個(gè)應(yīng)用都在其自己的Linux進(jìn)程內(nèi)運(yùn)行。Android系統(tǒng)會(huì)在需要執(zhí)行任何應(yīng)用組件時(shí)啟動(dòng)該進(jìn)程,然后當(dāng)不再需要該進(jìn)程或系統(tǒng)必須為其他應(yīng)用恢復(fù)內(nèi)存時(shí),其便會(huì)關(guān)閉該進(jìn)程。這里會(huì)有一個(gè)疑問:為什么說是默認(rèn)情況下呢?難道還有非默認(rèn)情況?
是的,非默認(rèn)情況就是android系統(tǒng)允許一個(gè)應(yīng)用可以有多個(gè)進(jìn)程,甚至不同的activity都能運(yùn)行在不同的進(jìn)程中(只要在AndroidManifest.xml對(duì)應(yīng)的activity節(jié)點(diǎn)下設(shè)置就可以);也允許不同的應(yīng)用運(yùn)行在同一個(gè)進(jìn)程中。這里要表達(dá)的是,進(jìn)程與進(jìn)程之間是獨(dú)立封閉的,所以一個(gè)進(jìn)程的運(yùn)行不會(huì)影響另一個(gè)進(jìn)程的運(yùn)行。最常見的例子是:應(yīng)用A crash了,并不會(huì)導(dǎo)致應(yīng)用B跟著crash
5、安卓系統(tǒng)實(shí)現(xiàn)了"最小權(quán)限"原則。即:每個(gè)應(yīng)用只能訪問執(zhí)行其工作所需的組件,而不能訪問其他組件。這樣便能創(chuàng)建非常安全的環(huán)境,在此環(huán)境中,應(yīng)用無法訪問其未獲得權(quán)限的系統(tǒng)部分。那這樣會(huì)有一個(gè)疑問:如果實(shí)在要實(shí)現(xiàn)應(yīng)用之間數(shù)據(jù)訪問呢?怎么辦?
安卓給出的答案是:
(1)可以安排兩個(gè)應(yīng)用共享同一 Linux 用戶 ID,在此情況下,二者便能訪問彼此的文件。為節(jié)省系統(tǒng)資源,也可安排擁有相同用戶 ID 的應(yīng)用在同一 Linux 進(jìn)程中運(yùn)行,并共享同一 VM。應(yīng)用還必須使用相同的證書進(jìn)行簽名。
(2)應(yīng)用可以請(qǐng)求訪問設(shè)備數(shù)據(jù)(如用戶的聯(lián)系人、短信消息、可裝載存儲(chǔ)裝置(SD 卡)、相機(jī)、藍(lán)牙等)的權(quán)限。但是必須申請(qǐng)對(duì)應(yīng)的權(quán)限并得到用于的允許。如果是系統(tǒng)app,那就不用,系統(tǒng)app擁有所有的權(quán)限
Q:怎么理解android app沒有單個(gè)入口點(diǎn)(即沒有main()函數(shù))?
A:個(gè)人理解之所有沒有單個(gè)入口點(diǎn)是基于app層,對(duì)于系統(tǒng)FrameWork層,還是有唯一的入口點(diǎn)的。具體理解如下:(如果有不對(duì)的地方,歡迎指正)
1、android系統(tǒng)設(shè)計(jì)的時(shí)候就將每個(gè)組件(activity,broadcast receiver,service,content provider)設(shè)計(jì)成相對(duì)獨(dú)立,這樣降低了組件之間的耦合度,并且為android將每個(gè)組件設(shè)計(jì)成單獨(dú)的可啟動(dòng)app的入口點(diǎn)創(chuàng)造了條件
2、基于1,安卓系統(tǒng)將每個(gè)組件都設(shè)計(jì)成可以啟動(dòng)該應(yīng)用的入口點(diǎn)。相當(dāng)于任何程序都可以啟動(dòng)另一個(gè)程序的組件。當(dāng)然,啟動(dòng)另外一個(gè)應(yīng)用是需要通過android系統(tǒng)的協(xié)助進(jìn)行的,相當(dāng)于將需要啟動(dòng)的組件"告知"系統(tǒng),系統(tǒng)找到包含該組件的app后,啟動(dòng)該進(jìn)程;然后調(diào)用該組件運(yùn)行起來。這樣設(shè)計(jì)給應(yīng)用開發(fā)帶來了極大的好處。舉個(gè)例子:你想在你的應(yīng)用中去拍照,不用開發(fā)一個(gè)"相機(jī)"APP,而只需要告知系統(tǒng)將系統(tǒng)自帶的"相機(jī)"APP運(yùn)行起來即可。更方便的是,不需要集成任何關(guān)于"相機(jī)"APP的代碼到你的應(yīng)用中
(3)基于以上兩點(diǎn),對(duì)于一個(gè)android app來說,每一個(gè)組件都是一個(gè)入口點(diǎn),每一個(gè)入口點(diǎn)都能讓系統(tǒng)啟動(dòng)該app正常運(yùn)行起來。對(duì)于其他系統(tǒng)來說,由于系統(tǒng)在單獨(dú)的進(jìn)程中運(yùn)行每個(gè)應(yīng)用程序,并且文件權(quán)限限制了對(duì)其他應(yīng)用程序的訪問,因此應(yīng)用程序無法直接從另一個(gè)應(yīng)用程序激活組件。而android系統(tǒng)在系統(tǒng)層面上將該缺陷解決掉了,這樣從app層看來,android的應(yīng)用程序擁有了多個(gè)入口點(diǎn)。而如果從系統(tǒng)層看來,啟動(dòng)app的過程的入口點(diǎn)還是那一個(gè)。
所以,個(gè)人理解,android app沒有入口點(diǎn)(沒有main()函數(shù))是從app層來看的;對(duì)于系統(tǒng)層,啟動(dòng)一個(gè)應(yīng)用,還是需要有對(duì)應(yīng)的唯一入口點(diǎn)的,如第一步一定要先執(zhí)行init()函數(shù)去初始化相關(guān)配置等等,因?yàn)閱?dòng)一個(gè)應(yīng)用的流程是固定的