JAVA啟動流程調(diào)試和程序結(jié)構(gòu).ppt
《JAVA啟動流程調(diào)試和程序結(jié)構(gòu).ppt》由會員分享,可在線閱讀,更多相關(guān)《JAVA啟動流程調(diào)試和程序結(jié)構(gòu).ppt(38頁珍藏版)》請在裝配圖網(wǎng)上搜索。
Android系統(tǒng)移植第九章Java啟動流程和程序結(jié)構(gòu) 一 java部分的啟動流程二 jni的基本概念三 jni的實(shí)現(xiàn)四 框架層中使用jni五 APK中使用jni 9 1java部分的啟動流程 Android系統(tǒng)的本地部分啟動完成后 將形成一系列的守護(hù)進(jìn)程 其中的名稱為zygote的守護(hù)進(jìn)程將繼續(xù)完成java部分的初始化 java部分初始化結(jié)束后 形成zygote SystemServer以及若干個java應(yīng)用的進(jìn)程 系統(tǒng)進(jìn)入正常運(yùn)行階段 9 1 1啟動流程概述 Android系統(tǒng)java部分的啟動主要涉及以下幾個實(shí)體 作為zygote運(yùn)行的本地可執(zhí)行程序 java框架庫中的zygoteInit java服務(wù)庫當(dāng)中的SystemServer和個服務(wù) java服務(wù)庫對應(yīng)的JNI本地庫libandroid sercers so 系統(tǒng)服務(wù)器的本地庫libandroid sercers so Java的啟動流程可以分成以下的幾個步驟 從本地可執(zhí)行程序運(yùn)行名為zygote的守護(hù)進(jìn)程Zygote運(yùn)行ZygoteInit 進(jìn)入java程序 ZygoteInit運(yùn)行SystemServer java類 并分裂出一個新的進(jìn)程 SystemServer首先運(yùn)行l(wèi)ibandroid sercers so庫當(dāng)中的初始化 進(jìn)入本地程序 執(zhí)行l(wèi)ibandroid sercers so當(dāng)中的系統(tǒng)初始化 SystemServer中的java初始化再次被調(diào)用 再入java程序 建立ServerThread線程 9 1 1啟動流程概述 ServerThread線程建立各個服務(wù) 然后進(jìn)出入循環(huán)ActivityManagerServer服務(wù)在啟動結(jié)束發(fā)送相關(guān)消息 各個java應(yīng)用程序運(yùn)行 啟動的過程中 經(jīng)歷了復(fù)雜的調(diào)用過程 有從本地到j(luò)ava的調(diào)用 有java之間的調(diào)用 有java調(diào)用本地 也有本地之間的調(diào)用 最終主要工作 在名稱為ServerThread的java線程中完成 Java啟動完成后 android進(jìn)入正常的運(yùn)行狀態(tài)中 此時 與java相關(guān)進(jìn)程主要有以下3個部分 Zygote 本質(zhì)是本地守護(hù)進(jìn)程 最終進(jìn)入循環(huán)狀態(tài) System server java的第一個守護(hù)進(jìn)程 其中也包括若干個線程 并進(jìn)入循環(huán) 各個java應(yīng)用程序 他們并行存在 互相依賴關(guān)系 從liunx系統(tǒng)運(yùn)行的角度上 SystemServe和各個java應(yīng)用程序內(nèi)的進(jìn)程都是zygote進(jìn)程的子進(jìn)程 9 1 1啟動流程概述 Androidjava部分的啟動流程如圖途中實(shí)線部分表示java系統(tǒng)相關(guān)的實(shí)體 其中有本地的內(nèi)容也有java的內(nèi)容 右側(cè)虛線框中的內(nèi)容分表示運(yùn)行時的進(jìn)程情況 在java的啟動過程中 java服務(wù)庫的重點(diǎn) 它調(diào)用了本地的部分初始化 然后建立了java層的各個服務(wù) 在系統(tǒng)正常的運(yùn)行過程中 這些服務(wù)是androidjava系統(tǒng)的公共部分和后臺部分 9 1 2java系統(tǒng)的守護(hù)進(jìn)程 Zygote是通過init進(jìn)程讀取的init rc啟動的一個守護(hù)進(jìn)程的民稱 在init rc中執(zhí)行性內(nèi)容的相關(guān)部分如下圖所示 名稱Zygote的服務(wù)的執(zhí)行者 實(shí)際上是 system bin app process的可執(zhí)行程序 后面的內(nèi)容是app process的執(zhí)行參數(shù) app process的代碼路徑為frameworks base cmds app process 生成名稱為app process的可執(zhí)行程序 會連接libandroid runtime so動態(tài)庫 間接連接Dalvik虛擬機(jī)的libdvm so庫調(diào)用Dalvik虛擬機(jī) 其中app mian cpp文件中的main 函數(shù)為可執(zhí)行程序入口 主要的代碼片段如下 9 1 2java系統(tǒng)的守護(hù)進(jìn)程 其中的appruntime實(shí)際上是運(yùn)行庫androidRuntime的繼承者 可以視為一個封裝類 app process執(zhí)行后 根據(jù)傳入的參數(shù)不同有兩條運(yùn)行路徑 第一個分支 當(dāng)命令具有 zygote參數(shù)的時候 將進(jìn)程的名稱設(shè)置為zygote然后調(diào)用java內(nèi)部的類zygoteinit 完成java環(huán)境第一步啟動 9 1 2java系統(tǒng)的守護(hù)進(jìn)程 第二個分支 當(dāng)命令程序沒有 zygote參數(shù)的時候 將進(jìn)程的名稱設(shè)置為第一個參數(shù) 然后根據(jù)類名啟動程序 App process可執(zhí)行程序作為zygote守護(hù)進(jìn)程運(yùn)行的時候 顯然調(diào)用的是第一個分支 根據(jù)參數(shù)的傳遞情況 其調(diào)用的是AppRuntime類的start 函數(shù)傳入的第一個參數(shù)為java的類名第二個參數(shù)為startsystemserver 根據(jù)命令行的參數(shù) 其數(shù)值為true 這個過程是在本地的進(jìn)程中 利用androidruntime執(zhí)行java的代碼 9 1 3Zygoteinit類的執(zhí)行 守護(hù)進(jìn)程zygote運(yùn)行后 com android internal os Zygoteinit進(jìn)入java環(huán)境中運(yùn)行 Zygoteinit是一個java框架庫 framework jar 中的內(nèi)部類 ZygoteInit java在farmeworks base core java com android internal os目錄中 其中的main 是一個android系統(tǒng)正常啟動后執(zhí)行的第一段java代碼 初始化過程中 zygote守護(hù)進(jìn)程調(diào)用ZygoteInit時 傳入的第一個參數(shù)為true 因此其中的startSystemServer 方法將會被執(zhí)行 9 1 3Zygoteinit類的執(zhí)行 startSystemServer 方法中的核心內(nèi)容如下所示 startSystemServer執(zhí)行了zygote forkSystemserver 完成了一次進(jìn)程的分裂 分裂出來的子進(jìn)程執(zhí)行了路徑為com android SystemServer的java類 這是java代碼中分裂另一個進(jìn)程的方法 分裂出的進(jìn)程就是系統(tǒng)服務(wù)器 它的名稱為system server 進(jìn)程分裂后 在父進(jìn)程中 startsystemsrver 方法將返回 ZygoteInit的main方法中代碼將繼續(xù)向下執(zhí)行 進(jìn)入有runforkmode或者runselectloopmode 構(gòu)建的循環(huán) 默認(rèn)是后者 執(zhí)行到這個地方 zygote守護(hù)進(jìn)程進(jìn)入了循環(huán) 而分裂出來的第一個java進(jìn)程 系統(tǒng)服務(wù)器 system server 將完成后續(xù)的java層初始化工作 9 1 4Zygoteinit類的執(zhí)行 main方法 System server進(jìn)程運(yùn)行的分類是com android SystemServer 這個類的內(nèi)容在java服務(wù)庫 server jar 當(dāng)中 SystemServer執(zhí)行過程中多次在java和本地直接切換 涉及的內(nèi)容還包括libandroid server so和libsystem server so兩個本地庫 Java層入口 SystemServer類的main 方法SystemServer類是服務(wù)包的主入口 在systmesrver java文件中是實(shí)現(xiàn) 代碼的路徑為 frameworks base service java com android server 當(dāng)這個類被調(diào)用后 執(zhí)行其main 代碼 System server運(yùn)行后加載了本地庫libandroid server so 然后執(zhí)行其中的init1 函數(shù) 調(diào)用了本地的初始化內(nèi)容 作為第一階段的初始化內(nèi)容 9 1 4Zygoteinit類的執(zhí)行 本地接口init1 Libandroid server so提供的是服務(wù)包的jni部分的支持 在java執(zhí)行過程中 又執(zhí)行了本地的調(diào)用 這種實(shí)現(xiàn)方式也就是在java系統(tǒng)的初始化過程中 插入了一段本地執(zhí)行的內(nèi)容 表示在特定的時機(jī) 完成部分本地初始化 Systemserver中執(zhí)行的init1 本地方方法 在frameworks base service jni目錄中的com android server systemserver cpp文件中 其中主要的內(nèi)容如下 這里實(shí)現(xiàn)了java中所需要的民稱為init1的本地調(diào)用 參數(shù)的內(nèi)容沒有進(jìn)行處理 而直接調(diào)用了本地的一個函數(shù)system init 9 1 4Zygoteinit類的執(zhí)行 system init System init 先完成本地的一些初始化 在調(diào)用java程序 最終進(jìn)入循環(huán) 這個函數(shù)在libsystem server so庫中實(shí)現(xiàn) 代碼路徑為 frameworks base cmds system server libary System init 首先執(zhí)完成本地相關(guān)的初始化 其中如果設(shè)置了 system init startsufaceflinger 屬性為1 則啟動surfacefilnger服務(wù) 如果本地的mediapalyerservice等服務(wù)沒有初始化 在此處也將啟動 然后得到j(luò)ava的運(yùn)行環(huán)境androidruntime 并調(diào)用com android server systemserver類中的名稱為init2靜態(tài)方法 此時由本地程序調(diào)用systemserver類中的java部分 9 1 4Zygoteinit類的執(zhí)行 system init 具體的系統(tǒng)實(shí)現(xiàn)中 如果有內(nèi)容需要在java系統(tǒng)正式執(zhí)行之前完成初始化 同樣可以將初始化的內(nèi)容放置到libsystme server so的system init 函數(shù)中 除此之外 frameworks base cmds system server目錄中的內(nèi)容將生成一個名稱為system server的可執(zhí)行程序 它連接了libsystem server so庫并調(diào)試了system init 完成等同于正常初始化的流程 System server可執(zhí)行程序只用于測試 正常啟動中不執(zhí)行 9 1 4Zygoteinit類的執(zhí)行 init2 方法 Systemserver類中的靜態(tài)方法init2 被本地調(diào)用后 system server進(jìn)程中的java代碼又再次被執(zhí)行 Init2 方法如下所示 這里調(diào)用了一個serverthread 它是一個java線程 thread 類的繼承者 在其中繼續(xù)完成后續(xù)的工作 實(shí)際上systemServer類當(dāng)中的兩個靜態(tài)方法main 和init2 并無直接的調(diào)用關(guān)系 而是經(jīng)過本地的間接調(diào)用 System server進(jìn)程的執(zhí)行流程為 mian init1 system init int2 兩端為java中的內(nèi)容 中間為本地的內(nèi)容 Systemserver類的init2 方法執(zhí)行后會返回 之后system server這個進(jìn)程的主線程將運(yùn)行位于libsystem server so中的system init 最后的循環(huán)中 9 1 4Zygoteinit類的執(zhí)行 serverthread Serverthread是systemserver java文件中和systemserver平行的一個類 它是java線程類thread的繼承者 負(fù)責(zé)建立各個java子服務(wù) Serverthread的核心內(nèi)容是其中的run 方法 執(zhí)行流程入下所示 serverthread 的初始化工作完成后 自己調(diào)用Looper loop 進(jìn)入循環(huán) 這里啟動的各個服務(wù)都是系統(tǒng)核心的重要部分 其中很多服務(wù)均會建立線程的后臺運(yùn)行 例如其中的幾個服務(wù)建立過程的片段如下 9 1 4Zygoteinit類的執(zhí)行 serverthread serverthread 的初始化工作完成后 自己調(diào)用Looper loop 進(jìn)入循環(huán) 這里啟動的各個服務(wù)都是系統(tǒng)核心的重要部分 其中很多服務(wù)均會建立線程的后臺運(yùn)行 例如其中的幾個服務(wù)建立過程的片段ServerThread的初始化流程是 首先建立關(guān)鍵 critical 的服務(wù) 例如以上的ActivityManagerService等 再建立各個次要服務(wù) 例如InputMethodManagerServer networkservice等 然后將調(diào)用很多服務(wù)中都具有的systemready 方法 等待每一個服務(wù)初始化完成 初始化完成后 serverthread才進(jìn)入looper loop 的循環(huán) SystemServer中的服務(wù) service 有時候這些服務(wù)又被稱之為 anderoid服務(wù) 區(qū)分于 本地服務(wù) 他們的實(shí)現(xiàn)其實(shí)只是一個名詞 并無實(shí)現(xiàn)類型的限制 上面的powermanagerservice 就是一個IXX stub的繼承者 因此通過servermanager將其加成服務(wù) 而activitymanagerservice則提供了靜態(tài)的main 方法來初始化 其實(shí)也是一個IXXX stub的繼承者 在main 方法中建立自己的實(shí)例 并增加到ServerManager Lightsservice則只是一個普通類 使用new建立實(shí)例即可 9 1 4Zygoteinit類的執(zhí)行 各個 服務(wù) 的執(zhí)行 當(dāng)系統(tǒng)初始化完成后 在android系統(tǒng)的正常運(yùn)行狀態(tài)中 SystemServer進(jìn)程中包含了多個線程 線程大部分是由system server中的服務(wù)所建立的 用于執(zhí)行每個服務(wù)當(dāng)中的后臺工作 線程和使用system server增加多少個服務(wù) binder的繼承者 沒有任何關(guān)系 只有在代碼中構(gòu)建了thread 才具有線程 在命令界面中執(zhí)行ps t可以查看system server進(jìn)程中的線程情況 查看的結(jié)果片段如下所示 1 EntropyServicekey entropy 2 PowerManagerServicekey power 3 ActivityManagerServicekey activityam工具命令 4 TelephonyRegistrykey telephony registry 5 PackageManagerServicepm工具命令 6 AccountManagerServicekey account 7 BatteryServicekey battery 8 HardwareServicekey hardware 9 AlarmManagerServicekey alarm 10 SensorServicekey sensor 11 WindowManagerServicekey window 9 1 4Zygoteinit類的執(zhí)行 各個 服務(wù) 的執(zhí)行 12 BluetoothServicekey bluetooth 13 BluetoothA2dpServicekey bluetooth a2dp 14 StatusBarServicekey statusbar 15 ClipboardServicekey clipboard 16 InputMethodManagerServicekey input method 17 NetStatServicekey netstat 18 ConnectivtiyServicekey connectivity 19 AccessibilityManagerServicekey accessibility 20 NotificationManagerServicekey notification 21 MountServicekey mount 22 DeviceStorageMonitorServicekey devicestoragemonitor 23 LocationManagerServicekey location 24 SearchManagerServicekey search 25 FallbackCheckinServicekey checkin 26 WallpaperManagerServicekey wallpaper 27 AudioServicekey audio 28 BackupManagerServicekey backup 29 AppWidgetServicekey appwidget 9 1 4Zygoteinit類的執(zhí)行 各個 服務(wù) 的執(zhí)行 此處眾多的父進(jìn)程id PID 為system server的id進(jìn)程 實(shí)際上都是system server中的線程 其中分成了各種不同的類型 HeapWorker GC SignalCatcher JDWP Compile幾個線程都是java環(huán)境所具有的 System Server是java環(huán)境的進(jìn)程 因此具有以上內(nèi)容 SurfaceFilnger等是從本地system init 中初始化過程中建立的本地線程 因此出現(xiàn)在交前的位置 Er serverthread是用于啟動各個java服務(wù)的線程 也就是serverthread 在serverthread之后就是activitymanager processstats packaemanager和windowmanager等 則是各個java服務(wù)的線程 Java全局的系統(tǒng)服務(wù)器初始化完畢后 有其中的某些服務(wù)發(fā)送服務(wù)信號 各個應(yīng)用程序的進(jìn)程被啟動 9 1 5java應(yīng)用程序部分的啟動 Java應(yīng)用程序部分的啟動原理是其中組件的調(diào)用 主要原因是java服務(wù)庫運(yùn)行后發(fā)送的各個intent 消息的發(fā)送各個應(yīng)用程序的啟動 一般都是由于系統(tǒng)服務(wù)器當(dāng)中的activitymanagerservice在初始化完成后發(fā)送了某種特殊的消息 其中造成應(yīng)用程序啟動的兩個原因是啟動了桌面 HOME 活動和發(fā)送了啟動結(jié)束 ACTION BOOT COMPLETED 廣播 Activitymanagerservice當(dāng)中的starthomeactivitylocked 方法和桌面啟動有關(guān)系 而finishbooting 將在啟動結(jié)束的時候被調(diào)用 其核心思想是包含一個動作名稱為Intent ACTION BOOT COMPLETED的intent發(fā)送廣播 因此各個應(yīng)用程序包當(dāng)中接受這個動作的BroadcastReceiver將有可能被運(yùn)行 9 1 5java應(yīng)用程序部分的啟動 各個java應(yīng)用程序包一般講成為一個獨(dú)立的進(jìn)程運(yùn)行 這些進(jìn)程也是zygote的子進(jìn)程 在這點(diǎn)上他們和system server進(jìn)程是相同的 因此 雖然應(yīng)用程序進(jìn)程和system server在啟動上有因果關(guān)系 但是在運(yùn)行時linux視他們?yōu)橥粋€進(jìn)程的子進(jìn)程 如果沒有特殊的情況下 所有的java進(jìn)程都是zygote的子進(jìn)程 各個java應(yīng)用程序的啟動是通過app process的第二個分支完成的 由于其中調(diào)用了set process name 因此每個java應(yīng)用程序的進(jìn)程名稱通常就是他們的java包 在系統(tǒng)啟動完成后可以查看java命令進(jìn)程情況 8 1android的java本地調(diào)用 Jni 8 1android的java本地調(diào)用 Jni 9 1 5java應(yīng)用程序部分的啟動 System server和各個應(yīng)用程序進(jìn)程的父進(jìn)程均為zygote 他們都是由zygote以類似的方式啟動起來的 系統(tǒng)不會立刻釋放每個應(yīng)用程序包上下文運(yùn)行 因此只需要一個應(yīng)用程包中有組件運(yùn)行過 他的進(jìn)程就會立即存在 在系統(tǒng)初始化階段之后 雖然沒有主動運(yùn)行某些應(yīng)用 但是此時已經(jīng)存在了一些各個應(yīng)用進(jìn)程 他是可能是由不同的方式被啟動的 由于某些包中的broadcastreceiver在接受了廣播后 得以運(yùn)行 因此它們雖然運(yùn)行完成但是應(yīng)用程序進(jìn)程依然存在 例如 com android lancher則作為桌面程序存在 他建立一些放置在桌面上的appwidet 窗口部件 因此實(shí)現(xiàn)這些窗口小部件的應(yīng)用程序包就已經(jīng)是啟動的進(jìn)程了 有一些數(shù)據(jù)庫想關(guān)的應(yīng)用程序包 需要在啟動后處理 因此其中的廣播接收器接收動作為ACTION BOOT COMPLETED的廣播 也已經(jīng)被運(yùn)行過了 9 2java層程序的結(jié)構(gòu)設(shè)計 本部分介紹java層的結(jié)構(gòu)化設(shè)計思路 指的是主體結(jié)構(gòu)子java層的程序 程序本身依然有本地調(diào)用 C C 的部分 主要需要關(guān)注的方面是android特有的java框架層和java應(yīng)用層的各中通信機(jī)制 9 2 1目標(biāo)和設(shè)計思路 在android的java層次中進(jìn)行框架性程序設(shè)計的時候 主要需要處理以下幾個方面的問題 1 兩個java進(jìn)程之間的程序 包括遠(yuǎn)程方法調(diào)用 2 在后臺長期運(yùn)行的程序 用來處理全局或者公共的內(nèi)容 3 程序間特定的通知 以上的三個方面中 第一個方面和第二個方面是后臺程序的基本內(nèi)容 他們也可以在本底層完成 但是第三個方面由于涉及android的java框架層和java應(yīng)用層各種特殊的通信機(jī)制 因此只能在java層完成 Android的java應(yīng)用層各種特殊的通信機(jī)制包括 使用android content包中的intent類 android app包中的pendingitent類和應(yīng)用程序?qū)拥慕M件 activity server或者broadcastreceiver 進(jìn)行交互 通過uri訪問某些內(nèi)容提供者 使用toast進(jìn)行提示 使用狀態(tài)欄的通知等 在java層的程序結(jié)構(gòu)化設(shè)計的核心是java層的binder機(jī)制 他可以完成兩個java進(jìn)程間相互調(diào)用的主要方面 9 2 1目標(biāo)和設(shè)計思路 在java層進(jìn)行框架層的設(shè)計 主要具有兩種典型的結(jié)構(gòu) 一種是在java框架層實(shí)現(xiàn)一個服務(wù) 作為系統(tǒng)服務(wù)的一部分 另一種形式是基于應(yīng)用層的service組件 兩種方式都可以實(shí)現(xiàn)后臺長期運(yùn)行的公共程序 一般他們實(shí)現(xiàn)的核心都基于java層的binder機(jī)制 8 1android的java本地調(diào)用 Jni 8 1android的java本地調(diào)用 Jni 8 1android的java本地調(diào)用 Jni 8 1android的java本地調(diào)用 Jni 8 1android的java本地調(diào)用 Jni 在android中提供的jni的方式 讓java程序可以調(diào)用C語言編寫的程序 android中很多java類具有native接口 這些native接口就是由本地實(shí)現(xiàn) 然后注冊到系統(tǒng)中的 在Android中主要的jni代碼在一下的路徑中 Frameworks base core jni 這個路徑中的內(nèi)容將被編譯成庫libandroid runtime so 這就是一個普通的動態(tài)庫 被放置在目標(biāo)系統(tǒng)的 system lib目錄中 除此之外 android還包含其他的jni庫 錄入媒體部分的jni在目錄frameworks base media jni中 被編譯成libmedia jni so Jni中的各個文件實(shí)際上就是C 的普通文件 其命令一般和支持的java類有對應(yīng)關(guān)系 這種關(guān)系式習(xí)慣上的寫法 而不是強(qiáng)制的 在android中實(shí)現(xiàn)的jni庫 需要連接動態(tài)庫libnativehelper so Jni在android層次結(jié)構(gòu)中的作用 8 1 1android的jni實(shí)現(xiàn) Jni在android層次結(jié)構(gòu)中的作用如圖所示 Android系統(tǒng)的jni和標(biāo)準(zhǔn)的java基本類似 實(shí)現(xiàn)jni主要的流程為在java源代碼中聲明本地方法 并注冊到對應(yīng)的java類中 在java層的聲明方面 android和標(biāo)準(zhǔn)的java使用了完全相同的方法 在本地層的實(shí)現(xiàn)方面 原本jni也沒有絕對完整的規(guī)則 android系統(tǒng)具有一定的特殊性 8 1 1android的jni實(shí)現(xiàn) 謝謝- 1.請仔細(xì)閱讀文檔,確保文檔完整性,對于不預(yù)覽、不比對內(nèi)容而直接下載帶來的問題本站不予受理。
- 2.下載的文檔,不會出現(xiàn)我們的網(wǎng)址水印。
- 3、該文檔所得收入(下載+內(nèi)容+預(yù)覽)歸上傳者、原創(chuàng)作者;如果您是本文檔原作者,請點(diǎn)此認(rèn)領(lǐng)!既往收益都?xì)w您。
下載文檔到電腦,查找使用更方便
9.9 積分
下載 |
- 配套講稿:
如PPT文件的首頁顯示word圖標(biāo),表示該P(yáng)PT已包含配套word講稿。雙擊word圖標(biāo)可打開word文檔。
- 特殊限制:
部分文檔作品中含有的國旗、國徽等圖片,僅作為作品整體效果示例展示,禁止商用。設(shè)計者僅對作品中獨(dú)創(chuàng)性部分享有著作權(quán)。
- 關(guān) 鍵 詞:
- JAVA 啟動 流程 調(diào)試 程序結(jié)構(gòu)
鏈接地址:http://appdesigncorp.com/p-6359816.html