⑴ 安卓原生系統是什麼意思
原生安卓系統(android)是指Google公司發布,沒有經過第三方修改的安卓系統,是操作系統最基層的也是最純凈的版本。
一般來說,主要是指各操作系統生產商最初建立的模型,各公司在模型的基礎上再不斷改進和優化,生產出不同的新版本。
(1)安卓源碼系統service擴展閱讀:
Android是一種基於Linux的自由及開放源代碼的操作系統,主要使用於移動設備,如智能手機和平板電腦,由Google公司和開放手機聯盟領導及開發。
尚未有統一中文名稱,中國大陸地區較多人使用「安卓」或「安致」。Android操作系統最初由Andy Rubin開發,主要支持手機。
2005年8月由Google收購注資。2007年11月,Google與84家硬體製造商、軟體開發商及電信營運商組建開放手機聯盟共同研發改良Android系統。
隨後Google以Apache開源許可證的授權方式,發布了Android的源代碼。第一部Android智能手機發布於2008年10月。
Android逐漸擴展到平板電腦及其他領域上,如電視、數碼相機、游戲機、智能手錶等。2011年第一季度,Android在全球的市場份額首次超過塞班系統,躍居全球第一。
2013年的第四季度,Android平台手機的全球市場份額已經達到78.1%。 2013年09月24日谷歌開發的操作系統Android在迎來了5歲生日,全世界採用這款系統的設備數量已經達到10億台。
2014第一季度Android平台已佔所有移動廣告流量來源的42.8%,首度超越iOS。但運營收入不及iOS。
參考資料:網路---原生安卓
⑵ Android源碼開發記錄-自定義系統服務和jar包生成
創建文件 IMyApiService
文件路徑 frameworks/base/core/java/android/os/
定義了一個計算和的方法。
在frameworks/base/Android.mk
LOCAL_SRC_FILES最後加入
創建文件 MyApiService.java
文件路徑 frameworks/base/core/java/com/android/server/
實現aidl的介面,計算參數和。
(1)Context添加服務名
文件路徑 frameworks/base/core/java/android/content/Context.java
添加
(2)添加啟動服務
文件路徑 frameworks/base/services/java/com/android/server/SystemServer.java
在startOtherServices方法中添加
創建 MyApiManager.java文件
文件路徑 frameworks/base/core/java/android/app/
文件路徑 frameworks/base/core/java/android/app/ContextImpl
添加registerService
記住make update-api
編譯打包完成後,燒寫新的固件。
jar主要為了在android studio編譯環境中MyApiManager報錯導致編譯不通過問題。
也可以導入frameworks jar包或使用反射。
在源碼目錄packages/app下新建MyJar文件夾
並新建目錄com/myapi/(包名)
在目錄com/myapi/新建文件MyApi.java
具體Android.mk語法這里不做解釋,可以自行查閱
在MyApi目錄下直接運行mm編譯命令(記得先source build/envsetup.sh)
待編譯完成後,jar生成目錄
out/target/common/obj/JAVA_LIBRARIES/Myapi_intermediates/javalib.jar
可更改為其他名稱。
⑶ android中handler和service的區別是什麼
任務、進程和線程
關於Android中的組件和應用,之前涉及,大都是靜態的概念。而當一個應用運行起來,就難免會需要關心進程、線程這樣的概念。在Android中,組件的動態運行,有一個最與眾不同的概念,就是Task,翻譯成任務,應該還是比較順理成章的。
Task的介入,最主要的作用,是將組件之間的連接,從進程概念的細節中剝離出來,可以以一種不同模型的東西進行配置,在很多時候,能夠簡化上層開發人員的理解難度,幫助大家更好的進行開發和配置。
任務
在SDK中關於Task(guide/topics/fundamentals.html#acttask),有一個很好的比方,說,Task就相當於應用(application)的概念。在開發人員眼中,開發一個Android程序,是做一個個獨門獨戶的組件,但對於一般用戶而言,它們感知到的,只是一個運行起來的整體應用,這個整體背後,就是Task。
Task,簡單的說,就是一組以棧的模式聚集在一起的Activity組件集合。它們有潛在的前後驅關聯,新加入的Activity組件,位於棧頂,並僅有在棧頂的Activity,才會有機會與用戶進行交互。而當棧頂的 Activity完成使命退出的時候,Task會將其退棧,並讓下一個將跑到棧頂的Activity來於用戶面對面,直至棧中再無更多 Activity,Task結束。
事件 Task棧
點開Email應用,進入收件箱(Activity A) A
選中一封郵件,點擊查看詳情(Activity B) AB
點擊回復,開始寫新郵件(Activity C) ABC
寫了幾行字,點擊選擇聯系人,進入選擇聯系人界面(Activity D) ABCD
選擇好了聯系人,繼續寫郵件 ABC
寫好郵件,發送完成,回到原始郵件 AB
點擊返回,回到收件箱 A
退出Email程序 null
如上表所示,是一個實例。從用戶從進入郵箱開始,到回復完成,退出應用整個過程的Task棧變化。這是一個標準的棧模式,對於大部分的狀況,這樣的Task 模型,足以應付,但是,涉及到實際的性能、開銷等問題,就會變得殘酷許多。比如,啟動一個瀏覽器,在Android中是一個比較沉重的過程,它需要做很多初始化的工作,並且會有不小的內存開銷。但與此同時,用瀏覽器打開一些內容,又是一般應用都會有的一個需求。設想一下,如果同時有十個運行著的應用(就會對應著是多個Task),都需要啟動瀏覽器,這將是一個多麼殘酷的場面,十個Task棧都堆積著很雷同的瀏覽器Activity,是多麼華麗的一種浪費啊。於是你會有這樣一種設想,瀏覽器Activity,可不可以作為一個單獨的Task而存在,不管是來自那個Task的請求,瀏覽器的Task,都不會歸並過去。這樣,雖然瀏覽器Activity本身需要維系的狀態更多了,但整體的開銷將大大的減少,這種舍小家為大家的行為,還是很值得歌頌的。
如此值得歌頌的行為,Android當然會舉雙手支持的。在Android中,每一個Activity的Task模式,都是可以由Activity提供方(通過配置文件...)和Activity使用方(通過Intent中的flag信息...)進行配置和選擇。當然,使用方對Activity的控制力,是限定在提供方允許的范疇內進行,提供方明令禁止的模式,使用方是不能夠越界使用的。
在SDK中(guide/topics/fundamentals.html#acttask),將兩者實現Task模式配置的方式,寫的非常清晰了,我再很絮叨挑選一些來解釋一下(完整可配置項,一定要看SDK,下面只是其中常用的若干項...)。提供方對組件的配置,是通過配置文件(Manifest)<activity>項來進行的,而調用方,則是通過Intent對象的flag進行抉擇的。相對於標準的Task棧的模式,配置的主要方向有兩個:一則是破壞已有棧的進出規則,或樣式;另一則是開辟新Task棧完成本應在同一Task棧中完成的任務。
對於應用開發人員而言,<activity>中的launchMode屬性,是需要經常打交道的。它有四種模式:"standard", "singleTop", "singleTask", "singleInstance"。
standard模式,是默認的也是標準的Task模式,在沒有其他因素的影響下,使用此模式的Activity,會構造一個Activity的實例,加入到調用者的Task棧中去,對於使用頻度一般開銷一般什麼都一般的Activity而言,standard模式無疑是最合適的,因為它邏輯簡單條理清晰,所以是默認的選擇。
而singleTop模式,基本上於standard一致,僅在請求的Activity正好位於棧頂時,有所區別。此時,配置成singleTop的Activity,不再會構造新的實例加入到Task棧中,而是將新來的Intent發送到棧頂Activity中,棧頂的Activity可以通過重載onNewIntent來處理新的Intent(當然,也可以無視...)。這個模式,降低了位於棧頂時的一些重復開銷,更避免了一些奇異的行為(想像一下,如果在棧頂連續幾個都是同樣的Activity,再一級級退出的時候,這是怎麼樣的用戶體驗...),很適合一些會有更新的列表Activity展示。一個活生生的實例是,在 Android默認提供的應用中,瀏覽器(Browser)的書簽Activity(BrowserBookmarkPage),就用的是singleTop。
singleTop模式,雖然破壞了原有棧的邏輯(復用了棧頂,而沒有構造新元素進棧...),但並未開辟專屬的Task。而singleTask,和singleInstance,則都採取的另闢Task的蹊徑。標志為singleTask的Activity,最多僅有一個實例存在,並且,位於以它為根的Task中。所有對該Activity的請求,都會跳到該Activity的Task中展開進行。singleTask,很象概念中的單件模式,所有的修改都是基於一個實例,這通常用在構造成本很大,但切換成本較小的Activity中。在Android源碼提供的應用中,該模式被廣泛的採用,最典型的例子,還是瀏覽器應用的主Activity(名為Browser...),它是展示當前tab,當前頁面內容的窗口。它的構造成本大,但頁面的切換還是較快的,於 singleTask相配,還是挺天作之合的。
相比之下,singleInstance顯得更為極端一些。在大部分時候singleInstance與singleTask完全一致,唯一的不同在於,singleInstance的Activity,是它所在棧中僅有的一個Activity,如果涉及到的其他Activity,都移交到其他Task中進行。這使得singleInstance的Activity,像一座孤島,徹底的黑盒,它不關注請求來自何方,也不計較後續由誰執行。在Android默認的各個應用中,很少有這樣的Activity,在我個人的工程實踐中,曾嘗試在有道詞典的快速取詞Activity中採用過,是因為我覺得快速取詞入口足夠方便(從notification中點選進入),並且會在各個場合使用,應該做得完全獨立。
除了launchMode可以用來調配Task,<activity>的另一屬性taskAffinity,也是常常被使用。taskAffinity,是一種物以類聚的思想,它傾向於將taskAffinity屬性相同的Activity,扔進同一個Task中。不過,它的約束力,較之launchMode而言,弱了許多。只有當<activity>中的allowTaskReparen ting設置為true,抑或是調用方將Intent的flag添加FLAG_ACTIVITY_NEW_TASK屬性時才會生效。如果有機會用到Android的Notification機制就能夠知道,每一個由notification進行觸發的Activity,都必須是一個設成FLAG_ACTIVITY_NEW_TASK的Intent來調用。這時候,開發者很可能需要妥善配置taskAffinity屬性,使得調用起來的Activity,能夠找到組織,在同一taskAffinity的Task中進行運行。
進程
在大多數其他平台的開發中,每個開發人員對自己應用的進程模型都有非常清晰的了解。比如,一個控制台程序,你可以想見它從main函數開始啟動一個進程,到 main函數結束,進程執行完成退出;在UI程序中,往往是有一個消息循環在跑,當接受到Exit消息後,退出消息循環結束進程。在該程序運行過程中,啟動了什麼進程,和第三方進程進行通信等等操作,每個開發者都是心如明鏡一本帳算得清清楚楚。進程邊界,在這里,猶如國界一般,每一次穿越都會留下深深的印跡。
在Android程序中,開發人員可以直接感知的,往往是Task而已。倍感清晰的,是組件邊界,而進程邊界變得難以琢磨,甚至有了進程託管一說。Android中不但剝奪了手工鍛造內存權力,連手工處置進程的權責,也毫不猶豫的獨佔了。
當然,Android隱藏進程細節,並不是刻意為之,而是自然而然水到渠成的。如果,我們把傳統的應用稱為面向進程的開發,那麼,在Android中,我們做得就是面向組件的開發。從前面的內容可以知道,Android組件間的跳轉和通信,都是在第三方介入的前提下進行,正由於這種介入,使得兩個組件一般不會直接發生聯系(於Service的通信,是不需要第三方介入的,因此Android把它全部假設成為穿越進程邊界,統一基於RPC來通信,這樣,也是為了掩蓋進程細節...),其中是否穿越進程邊界也就變得不重要。因此,如果這時候,還需要開發者關注進程,就會變得很奇怪,很費解,乾脆,Android將所有的進程一並託管去了,上層無須知道進程的生死和通信細節。
在Android的底層,進程構造了底部的一個運行池,不僅僅是Task中的各個Activity組件,其他三大組件Service、Content Provider、Broadcast Receiver,都是寄宿在底層某個進程中,進行運轉。在這里,進程更像一個資源池(概念形如線程池,上層要用的時候取一個出來就好,而不關注具體取了哪一個...),只是為了承載各個組件的運行,而各個組件直接的邏輯關系,它們並不關心。但我們可以想像,為了保證整體性,在默認情況下,Android肯定傾向於將同一Task、同一應用的各個組件扔進同一個進程內,但是當然,出於效率考慮,Android也是允許開發者進行配置。
在Android中,整體的<application>(將影響其中各個組件...)和底下各個組件,都可以設置<process>屬性,相同<process>屬性的組件將扔到同一個進程中運行。最常見的使用場景,是通過配置<application>的process屬性,將不同的相關應用,塞進一個進程,使得它們可以同生共死。還有就是將經常和某個Service組件進行通信的組件,放入同一個進程,因為與Service通信是個密集操作,走的是RPC,開銷不小,通過配置,可以變成進程內的直接引用,消耗頗小。
除了通過<process>屬性,不同的組件還有一些特殊的配置項,以Content Provider為例(通過<provider>項進行配置...)。<provider>項有一個mutiprocess的屬性,默認值為false,這意味著Content Provider,僅會在提供該組件的應用所在進程構造一個實例,第三方想使用就需要經由RPC傳輸數據。這種模式,對於構造開銷大,數據傳輸開銷小的場合是非常適用的,並且可能提高緩存的效果。但是,如果是數據傳輸很大,抑或是希望在此提高傳輸的效率,就需要將mutiprocess設置成true,這樣,Content Provider就會在每一個調用它的進程中構造一個實例,避免進程通信的開銷。
既然,是Android系統幫助開發人員託管了進程,那麼就需要有一整套紛繁的演算法去執行回收邏輯。Android中各個進程的生死,和運行在其中的各個組件有著密切的聯系,進程們依照其上組件的特點,被排入一個優先順序體系,在需要回收時,從低優先順序到高優先順序回收。Android進程共分為五類優先順序,分別是:Foreground Process, Visible Process, Service Process, Background Process, Empty Process。顧名思義不難看出,這說明,越和用戶操作緊密相連的,越是正與用戶交互的,優先順序越高,越難被回收。具體詳情,參見:guide/topics/fundamentals.html#proclife。
有了優先順序,還需要有良好的回收時機。回收太早,緩存命中概率低可能引起不斷的創造進程銷毀進程,池的優勢盪然無存;回收的太晚,整體開銷大,系統運行效率降低,好端端的法拉利可能被糟蹋成一枚QQ老爺車。Android的進程回收,最重要的是考量內存開銷,以及電量等其他資源狀況,此外每個進程承載的組件數量、單個應用開辟的進程數量等數量指標,也是作為衡量的一個重要標識。另外,一些運行時的時間開銷,也被嚴格監控,啟動慢的進程會很被強行kill掉。Android會定時檢查上述參數,也會在一些很可能發生進程回收的時間點,比如某個組件執行完成後,來做回收的嘗試。
從用戶體驗角度來看,Android的進程機制,會有很可喜的一面,有的程序啟動速度很慢,但是在資源充沛的前提下,你反復的退出再使用,則啟動變得極其快速(進程沒死,只是從後台弄到了前台),這就是拜進程託管所賜的。當然,可喜的另一面就是可悲了,Android的託管演算法,還時不時的展現其幼稚的一面,明明用戶已經明顯感覺到操作系統運行速度下降了,打開任務管理器一看,一票應用還生龍活虎的跳躍著,必須要手動幫助它們終結生命找到墳墓,這使得任務管理器基本成為Android的裝機必備軟體。
從開發角度上來看,Android這套進程機制,解放了開發者的手腳。開發人員不需要處心積慮的構造一個後台進程偷偷默默監聽某個時間,並嘗試用各種各樣的守護手段,把自己的進程鍛造的猶如不死鳥一輝一般,進程生死的問題,已經原理了普通開發人員需要管理的范疇內。但同時,於GC和人肉內存管理的爭議一樣,所有開發人員都不相信演算法能比自己做得效率更高更出色。但我一直堅信一點,所有效率的優勢都會隨著演算法的不斷改良硬體的不斷提升而消失殆盡,只有開發模式的簡潔不會隨時間而有任何變化。
組件生命周期
任何架構上的變化,都會引起上層開發模式的變化,Android的進程模型,雖然使開發者不再需要密切關注進程的創建和銷毀的時機,但仍然需要關注這些時間點對組件的影響。比如,你可能需要在進程銷毀之前,將寫到內存上的內容,持久化到硬碟上,這就需要關注進程退出前發生的一些事件。
在Android中,把握這些時間點,就必須了解組件生命周期(Components Lifecycles)。所謂組件的生命在周期,就是在組件在前後台切換、被用戶創建退出、被系統回收等等事件發生的時候,會有一些事件通知到對應組件上,開發人員可以選擇性的處理這些事件在對應的時間點上來完成一些附加工作。
除Content Provider,其他組件都會有生命周期的概念,都需要依照這個模型定時定點處理一些狀況,全部內容參見:guide/topics/fundamentals.html#lcycles。在這里,擒賊先擒王,還是拿Activity出來作楷模。
繼續偷圖,來自SDK。一個自然的Activity生命旅途,從onCreate開始,到onDestroy消亡。但月有陰晴圓缺組件有禍福旦夕,在系統需要的時候且組件位於後台時,所在的進程隨時可能為國捐軀被回收,這就使得知道切入後台這個事情也變得很重要。
當組件進入棧頂,與用戶開始交互,會調用onResume函數,類似,當退出棧頂,會有onPause函數被呼喚。onResume和onPause可以處理很多事情,最常規的,就是做一些文件或設置項的讀寫工作。因為,在該組件不再前台運行的時候,可能別的組件會需要讀寫同樣一份文件和設置,如果不再onResume做刷新工作,用的可能就是一份臟數據了(當然,具體情況,還需要具體分析,如果文件不會被多頭讀寫,可以放到onCreate裡面去做讀工作)。
除了前述切入後台會被其他組件騷擾的問題,另外,死無定因也是件很可怕的事情。在Android中,組件都有兩種常見的死法,一種是自然消亡,比如,棧元素ABC,變成AB了,C組件就自然消亡了。這種死發輕如鴻毛,不需要額外關心。但另一種情況,就是被系統回收,那是死的重如泰山,為國捐軀嘛。
但這種捐軀的死法,對用戶來說,比較費解。想像一下,一款游戲,不能存檔,你一直玩啊玩,三天三夜沒合眼,這時候你mm打來電話鼓勵一下,你精神抖擻的准備再接再厲,卻發現你的游戲進程,在切入後台之後,被系統回收了,一夜回到解放前三天努力成為一場泡影,你會不會想殺做游戲的人,會不會會不會會不會,一定會嘛。這時候,如果沒有Activity生命周期這碼事,游戲程序員一定是被冤死的,成了Android的替罪羊。但是,Android的組件是有生命周期的, 如果真的發生這樣情況,不要猶豫,去殺開發的程序員吧。
為了逃生,程序員們有一塊免死金牌,那就是Android的state機制。所謂state,就是開發人員將一些當前運行的狀態信息存放在一個Bundle對象裡面,這是一個可序列化鍵值對集合。如果該Activity組件所處的進程需要回收,Android核心會將其上Activity組件的Bundle對象持久化到磁碟上,當用戶回到該Activity時候,系統會重新構造該組件,並將持久化到磁碟上的Bundle對象恢復。有了這樣的持久化的狀態信息,開發人員可以很好的區分具體死法,並有機會的使得死而復生的Activity恢復到死前狀態。開發者應該做的,是通過onSaveInstanceState函數把需要維系的狀態信息(在默認的狀態下,系統控制項都會自己保存相關的狀態信息,比如TextView,會保存當前的Text信息,這都不需要開發人員擔心...),寫入到Bundle對象,然後在onRestoreInstanceState函數中讀取並恢復相關信息(onCreate,onStart,也都可以處理...)。
線程
讀取數據,後台處理,這些猥瑣的伙計,自然少不了線程的參與。在Android核心的調度層面,是不屑於考量線程的,它關注的只有進程,每一個組件的構造和處理,都是在進程的主線程上做的,這樣可以保證邏輯的足夠簡單。多線程,往往都是開發人員需要做的。
Android的線程,也是通過派生Java的Thread對象,實現Run方法來實現的。但當用戶需要跑一個具有消息循環的線程的時候,Android有更好的支持,來自於Handler和Looper。Handler做的是消息的傳送和分發,派生其handleMessage函數,可以處理各種收到的消息,和win開發無異。Looper的任務,則是構造循環,等候退出或其他消息的來臨。在Looper的SDK頁面,有一個消息循環線程實現的標准範例,當然,更為標準的方式也許是構造一個HandlerThread線程,將它的Looper傳遞給Handler。
在Android中,Content Provider的使用,往往和線程掛鉤,誰讓它和數據相關呢。在前面提到過,Content Provider為了保持更多的靈活性,本身只提供了同步調用的介面,而由於非同步對Content Provider進行增刪改查是一個常做操作,Android通過AsyncQueryHandler對象,提供了非同步介面。這是一個Handler的子類,開發人員可以調用startXXX方法發起操作,通過派生onXXXComplete方法,等待執行完畢後的回調,從而完成整個非同步調用的流程,十分的簡約明了。
實現
整個任務、進程管理的核心實現,盡在ActivityManagerService中。上一篇說到,Intent解析,就是這個ActivityManagerService來負責的,其實,它是一個很名不副實的類,因為雖然名為Activity的Manager Service,但它管轄的范圍,不只是Activity,還有其他三類組件,和它們所在的進程。
在ActivityManagerService中,有兩類數據結構最為醒目,一個是ArrayList,另一個是HashMap。 ActivityManagerService有大量的ArrayList,每一個組件,會有多個ArrayList來分狀態存放。調度工作,往往就是從一個ArrayList裡面拿出來,找個方法調一調,然後扔到另一個ArrayList裡面去,當這個組件沒對應的ArrayList放著的時候,說明它離死不遠了。HashMap,是因為有組件是需要用名字或Intent信息做定位的,比如Content Provider,它的查找,都是依據Uri,有了HashMap,一切都順理成章了。
ActivityManagerService用一些名曰xxxRecord的數據結構,來表達各個存活的組件。於是就有了,HistoryRecord(保存Activity信息的,之所以叫History,是相對Task棧而言的...),ServiceRecord,BroadcastRecord,ContentProviderRecord,TaskRecord,ProcessRecord,等等。
值得注意的,是TaskRecord,我們一直再說,Task棧這樣的概念,其實,真實的底層,並不會在TaskRecord中,維系一個Activity 的棧。在ActivityManagerService中,各個任務的Activity,都以HistoryRecord的形式,集中存放在一個 ArrayList中,每個HistoryRecord,會存放它所在TaskRecord的引用。當有一個Activity,執行完成,從概念上的 Task棧中退出,Android是通過從當前HistoryRecord位置往前掃描同一個TaskRecord的HistoryRecord來完成的。這個設計,使得上層很多看上去邏輯很復雜的Task體系,在實現變得很統一而簡明,值得稱道。
ProcessRecord,是整個進程託管實現的核心,它存放有運行在這個進程上,所有組件的信息,根據這些信息,系統有一整套的演算法來決議如何處置這個進程,如果對回收演算法感興趣,可以從ActivityManagerService的trimApplications函數入手來看。
對於開發者來說,去了解這部分實現,主要是可以幫助理解整個進程和任務的概念,如果覺得這塊理解的清晰了,就不用去碰ActivityManagerService這個龐然大物了。
================
這是轉載的 ,感覺比一樓說的好
=============
一下是自己的
服務(Service)需要配置 才能使用
線程 使用就不說了
hanler ,是用來進行消息隊列的一個東東,handler 可以用來更新控制項的顯示 ,以及線程之間的通信,
service只能啟動後台,屬於應用組件之一
⑷ android怎麼修改源碼
1、通過 ubuntu 軟體中心安裝 wine;
2、通過 ubuntu 軟體中心安裝 winetricks;
3、通過 winetricks 在 shell中輸入: winetricks mfc42
1、通過 wine windows 的方式啟動代理伺服器
2、設置瀏覽器代理伺服器
3、設置shell代理伺服器:
在shell中輸入 sudo gedit /etc/bash.bashrc
在文件 /etc/bash.bashrc 中添加
通過shell安裝如下的組件:
1、sudo apt-get install bison g++-multilib git gperf libxml2-utils
2、新建一個存放源碼的目錄,如:mkdir ~/andorid/source
3、在源碼目錄中輸入命令:repo init -u -b android-4.0.1_r1
其中: android-4.0.1_r1是android源碼的版本,更多的版本可以通過下面的方式查詢:
4、修改source/.repo/manifest/default.xml 文件中的 fetch 的值為:
git://Android.git.linaro.org/
通過如下的指令來設置郵箱和用戶名
git config --global user.name "<your name>" ----修改用戶名git config --global user.email "<your email>" ----修改email
5、在source目錄下輸入指令:repo sync
便開始了代碼的下載
方便他人亦是方便自己,如果覺得還行就點下下邊的投票吧,這樣可以幫助其他人更快的找到解決問題的方法;有疑問的也可留言哦, 謝謝!
⑸ 最近在看android音樂播放器的源碼,發現播放音樂等操作都是用service來進行的,這樣做有什麼好處求解
首先service的啟動方式有兩種,Context.startService()方式啟動和Context.bindService()方式啟動.前者如果你的程序退出時不停止Service,它會在後台一直運行.後者是跟你的程序綁定了,你的程序退出時Service也停止了.詳細的你去查一下.用Service的好處就是當你的程序進入後台時,不影響音樂的播放.如果沒有把播放音樂寫在Service中當你的播放器進入後台或者退出時音樂就停止了.
⑹ Android源碼解析Window系列第(一)篇---Window的基本認識和Activity的載入流程
您可能聽說過View ,ViewManager,Window,PhoneWindow,WindowManager,WindowManagerService,可是你知道這幾個類是什麼關系,幹嘛用的。概括的來說,View是放在Window中的,Window是一個抽象類,它的具體實現是PhoneWindow,PhoneWindow還有個內部類DecorView,WindowManager是一個interface,繼承自ViewManager,它是外界訪問Window的入口,,提供了add/remove/updata的方法操作View,WindowManager與WindowManagerSerice是個跨進程的過程,WindowManagerService的職責是對系統中的所有窗口進行管理。如果您不太清楚,建議往下看,否則就不要看了。
Android系統的Window有很多種,大體上來說,Framework定義了三種窗口類型;
這就是Framework定義了三種窗口類型,這三種類型定義在WindowManager的內部類LayoutParams中,WindowManager講這三種類型 進行了細化,把每一種類型都用一個int常量來表示,這些常量代表窗口所在的層,WindowManagerService在進行窗口疊加的時候,會按照常量的大小分配不同的層,常量值越大,代表位置越靠上面, 所以我們可以猜想一下,應用程序Window的層值常量要小於子Window的層值常量,子Window的層值常量要小於系統Window的層值常量。 Window的層級關系如下所示。
上面說了Window分為三種,用Window的type區分,在搞清楚Window的創建之前,我們需要知道怎麼去描述一個Window,我們就把Window當做一個實體類,給我的感覺,它必須要下面幾個欄位。
實際上WindowManager.LayoutParams對Window有很詳細的定義。
提取幾個重要的參數
Window是一個是一個抽象的概念,千萬不要認為我們所看到的就是Window,我們平時所看到的是視圖,每一個Window都對應著一個View,View和Window通過ViewRootImpl來建立聯系。有了View,Window的存在意義在哪裡呢,因為View不能單獨存在,它必須依附著Window,所以有視圖的地方就有Window,比如Activity,一個Dialog,一個PopWindow,一個菜單,一個Toast等等。
通過上面我們知道視圖和Window的關系,那麼有一個問題,是先有視圖,還是先有Window。這個答案只有在源碼中找了。應用程序的入口類是ActivityThread,在ActivityThread中有performLaunchActivity來啟動Activity,這個performLaunchActivity方法內部會創建一個Activity。
如果activity不為null,就會調用attach,在attach方法中通過PolicyManager創建了Window對象,並且給Window設置了回調介面。
PolicyManager的實現類是Policy
這樣Window就創建出來了, 所以先有Window,後有視圖,視圖依賴Window存在 ,再說一說視圖(Activity)為Window設置的回調介面。
Activity實現了這個回調介面,當Window的狀態發生變化的時候,就會回調Activity中實現的這些介面,有些回調介面我們還是熟悉的,dispatchTouchEvent,onAttachedToWindow,onDetachedFromWindow等。
下面分析view是如何附屬到window上的,通過上面可以看到,在attach之後就要執行callActivityOnCreate,在onCreate中我們會調用setContentView方法。
getWindow獲取了Window對象,Window的具體實現類是PhoneWindow,所以要看PhoneWindow的setContentView方法。
這里涉及到一個mContentParent變數,他是一個DecorView的一部分,DecorView是PhoneWindow的一個內部類,我先介紹一下關於DecorView的知識。
DecorView是Activity的頂級VIew,DecorView繼承自FrameLayout,在DecorView中有上下兩個部分,上面是標題欄,下面是內容欄,我們通過PhoneWindow的setContentView所設置的布局文件是加到內容欄(mContentParent)裡面的,View層的事件都是先經過DecorView在傳遞給我們的View的。
OK在回到setContentView的源碼分析,我們可以得到Activity的Window創建需要三步。
- 1、 如果沒有DecorView,在installDecor中創建DecorView。
- 2、將View添加到decorview中的mContentParent中。
- 3、回調Activity的onContentChanged介面。
先看看第一步,installDecor的源碼
installDecor中調用了generateDecor,繼續看
直接給new一個DecorView,有了DecorView之後,就可以載入具體的布局文件到DecorView中了,具體的布局文件和系統和主題有關系。
在看第二步,將View添加到decorview中的mContentParent中。
直接將Activity視圖加到DecorView的mContentParent中,最後一步,回調Activity的onContentChanged介面。在Activity中尋找onContentChanged方法,它是個空實現,我們可以在子Activity中處理。
到此DecorView被創建完畢,我們一開始從Thread中的handleLaunchActivity方法開始分析,首先載入Activity的位元組碼文件,利用反射的方式創建一個Activity對象,調用Activity對象的attach方法,在attach方法中,創建系統需要的Window並為設置回調,這個回調定義在Window之中,由Activity實現,當Window的狀態發生變化的時候,就會回調Activity實現的這些回調方法。調用attach方法之後,Window被創建完成,這時候需要關聯我們的視圖,在handleLaunchActivity中的attach執行之後就要執行handleLaunchActivity中的callActivityOnCreate,在onCreate中我們會調用setContentView方法。通過setContentView,創建了Activity的頂級View---DecorView,DecorView的內容欄(mContentParent)用來顯示我們的布局。 這個是我們上面分析得到了一個大致流程,走到這里,這只是添加的過程,還要有一個顯示的過程,顯示的過程就要調用handleLaunchActivity中的handleResumeActivity方法了。最後會調用makeVisible方法。
這裡面首先拿到WindowManager對象,用tWindowManager 的父介面ViewManager接收,ViewManager可以
最後調用 mDecor.setVisibility(View.VISIBLE)設置mDecor可見。到此,我們終於明白一個Activity是怎麼顯示在我們的面前了。
參考鏈接:
http://blog.csdn.net/feiclear_up/article/details/49201357
⑺ Android Service啟動Activity
Android Service 基礎知識點
我們都知道Activity中啟動Activity,只需要startActivity,如果在Service中啟動Activity呢?
在Service中啟動Activity,很多人說在非Activity中啟動Activity需要加FLAG_ACTIVITY_NEW_TASK flag,如果我不加會怎麼樣呢?
並沒有出現異常和崩潰,跳轉也是正常的,但是與之前所說的會崩潰報出異常不符合啊?!難道是與版本有關嗎?大友於是我使用了Android 23去測試果然拋出了異常
ContextImpl在Android studio中屬於隱藏源碼,在IDE中可能看不到,那就需要在SDK中去找 我的是:D:\AndroidSdk\sources\android-23\android\app\ContextImpl.java
可以看到只是判斷條件不同而已,android-23中發現沒有Intent.FLAG_ACTIVITY_NEW_TASK會直接拋出異常,而android-26中我們在非 Activity 調用 startActivity() 的時候,我們這個 options 通常是 null 的,所以在 26 之間的時候,誤把判斷條件 options == null 寫成了 options != null 導致進不去 if,從而不會拋出異常
附加:在android 24-android 27(即android N-android O)之間出現了bug,也就是說即使沒有加Intent.FLAG_ACTIVITY_NEW_TASK也會正常跳轉激仿銷
可以很明顯看到判斷條件targetSdkVersion <明游 Build.VERSION_CODES.N || targetSdkVersion >= Build.VERSION_CODES.P 即在24-27
看Activity中啟動Activity的源碼
Activity.startActivity() ->startActivityForResult()->mInstrumentation.execStartActivity() ...最終還是Ams去啟動Activity 也就是Activity中重寫了startActivity()方法所以不會出現這個異常
其實直觀很好理解,如果不是在Activity中啟動的,那就可以看做不是用戶主動的行為,也就說這個界面可能出現在任何APP之上,如果不用Intent.FLAG_ACTIVITY_NEW_TASK將其限制在自己的Task中,那用戶可能會認為該Activity是當前可見APP的頁面,這是不合理的。舉個例子:我們在聽音樂,這個時候如果郵件Service突然要打開一個Activity,如果不用Intent.FLAG_ACTIVITY_NEW_TASK做限制,那用戶可能認為這個Activity是屬於音樂APP的,因為用戶點擊返回的時候,可能會回到音樂,而不是郵件(如果郵件之前就有界面)
對比源碼發現,在我們非 Activity 調用 startActivity() 的時候,我們這個 options 通常是 null 的,所以在 24~27 之間的時候,誤把判斷條件 options == null 寫成了 options != null 導致進不去 if,從而不會拋出異常,如此我們使用 Context.startActivity() 的時候是一定要加上 FLAG_ACTIVITY_NEW_TASK 的,但是在 Android N 到 O-MR1,即 24~27 之間卻出現了 bug,即使沒有加也會正確跳轉
結語:感謝各位大佬的分享,對此有疑問的可以去運行跑一下,看一下相關的源碼,如有錯誤的需要改進的地方,請留言評論指出,謝謝!
參考文章:
⑻ 怎樣評價羅升陽的android系統源代碼分析
我幹了3年Android sdk開發,覺得到了瓶勁沒法更進一步,於是花了一年多點時間,大概摸到點門徑。根據前輩的經驗,Android底層完全入門需要兩年。 先說下我的入門過程: 第零步,下載源碼,我下的4.2的,框架層源碼10G,內核2G多,ctags給框架層建的標簽文件都有600M,當時讓我有點震撼,用的vim+ctags+cscope來閱讀,還算不錯,架構挺清晰的。 第一步,我找到了一本好書《Android的設計與實現 第一卷》它講了Android框架層的啟動,初始化,服務框架初始化,Binder,消息循環,PackageManagerService,ActivityManagerService。據作者說後面會出講UI子系統的第二卷,拭目以待。其實這本書看了幾十頁我就發現需要第二步的知識,否則看不下去,於是跳去第二步。 第二步,學習Linux系統編程,在看《Android的設計與實現》的時候我發現,框架層的Native部分,全是Linux編程。為了掌握這部分知識,我花了4個月學習了《Linux系統編程手冊》(TLPI)這本1000多頁的書,我以前是搞WIndows文件系統這塊的,所以C語言還比較熟,TLPI的習題很有意思,量也比較大,堅持下來還是收獲很多。 第三步,花了4個月學習了一些Linux內核的知識,看了LKD,PLKA看了一半多。越學越沒底,覺得不懂得越來越多,不過這個也正常,只有靠慢慢磨,估計以後要不斷的磨這塊。 第四步,回頭看Android源碼,這次一口氣看完了《Android的設計與實現 第一卷》,終於對框架層有了譜。同時真的數次把我看暈,前面看Linux內核源碼都沒這么暈,不斷在Java層和Native層之間跳有點磨腦漿。其中我又覺得Java的基礎沒有打太牢,回去補了一個月的《Core Java》第八版。但是這書沒有涉及UI子系統,於是又看了《Android內核剖析》 第五步,《Android內核剖析》(這本書實際上是講框架層的,作者也是個搞嵌入式的,所以他在寫框架層的時候文筆不太好,很羅嗦,不過還是有很多看點,到他後來寫做ROM,玩開發板時估計是說到了他的本行,一下子遛起來了看得出還是挺有水平的,這本書知識有點舊畢竟講的是2.3很多代碼已經過時,但是作者很多點子很有參考價值)這本書講UI子系統和按鍵/觸摸消息處理系統還是很有分量的,尤其13章View繪制那裡,結合源碼研究很有收獲。而後面他講編譯框架和ROM相關的東西都是挺寶貴的資料。 第六步,為了再補一下其他諸如電源管理模塊等子系統的知識看了,《深入理解android》系列,個人認為這個系列看起來有點不太舒服,不過作為補充印證還是比較有價值。 第七步,《Android系統源代碼情景分析》,羅升陽的源碼分析大作,比《Android的設計與實現》分析得更細致,但缺點是涉及到模塊比較少,選用的源碼也比《Android的設計與實現》更舊一點。看完書後需要去研究作者的博客,東西挺多的,一定讓你滿意。 第八步,買塊開發板自己玩。這步我還沒走到,原因是我覺得我還差點准備知識。可能要再幾個月,到時准備入塊6410或者樹莓派。 最後,由於我11年以前都是搞Windows這塊的,所以對Linux知識不是很了解,不得已看了這么些書,如果是一直做Linux的人,很多步驟估計可以省掉了。直接上源碼才是正道。 我本身做著移動GIS開發的工作,學框架層全是因為興趣,但招聘平台Android框架層開發人員還是蠻有競爭力的有不少定製ROM,智能電視的工作都處於人才難求狀態,畢竟有一定的門檻,現在各種ios培訓,讓奔著錢干開發的人紛紛湧入,而ios只能幹sdk開發的缺點就暴露出來了,一堆新手老手,菜鳥大牛全擠在SDK開發這塊,我覺得不太妙。 反觀Android這邊,雖然入門菜鳥沒有搞ios來錢,但是可持續性很好,從sdk-》框架》驅動》內核這樣幹下去。干著干著發現自己漸漸變成了Linux開發者/嵌入式開發者的人也不少,新人,老手,菜鳥大牛各居其位,層次性很好。 轉載