国产成人精品三级麻豆,色综合天天综合高清网,亚洲精品夜夜夜,国产成人综合在线女婷五月99播放,色婷婷色综合激情国产日韩

當(dāng)前位置:首頁(yè) > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > Android init進(jìn)程之如何進(jìn)入java世界

Android init進(jìn)程之如何進(jìn)入java世界 時(shí)間:2018-09-26      來源:未知

上一節(jié)我們了解了一下Android的init啟動(dòng)流程,我們知道在init進(jìn)程啟動(dòng)的過程中,開啟 了很多服務(wù)。我們也知道Android上層的應(yīng)用程序是用Java語(yǔ)言編寫的,Java語(yǔ)言編寫的 程序需要放在Java虛擬機(jī)中運(yùn)行,為了提高Android App應(yīng)用程序的效率,google公司提 供了經(jīng)過優(yōu)化之后的Dalvik虛擬機(jī)來運(yùn)行上層Java語(yǔ)言編寫的程序。

好了,拋出兩個(gè)問題:

1、Android系統(tǒng)是如何從C/C++世界進(jìn)入Java世界的呢?

2、Android系統(tǒng)是如何運(yùn)行上層的APP應(yīng)用程序的呢?

一、zygote進(jìn)程介紹

回顧上一節(jié)我們知道init進(jìn)程在啟動(dòng)過程中啟動(dòng)了一個(gè)叫做zygote服務(wù)。在Android 中,zygote是整個(gè)系統(tǒng)創(chuàng)建新進(jìn)程的核心裝置。從字面上看,zygote是受精卵的意思,它 的主要工作就是進(jìn)行細(xì)胞分裂。zygote進(jìn)程內(nèi)部會(huì)先啟動(dòng)Dalvik虛擬機(jī),繼而加載一些必 要的系統(tǒng)資源和系統(tǒng)類,后進(jìn)入一種監(jiān)聽狀態(tài)。在后續(xù)的運(yùn)作中,當(dāng)其他系統(tǒng)模塊(比 如AMS)希望創(chuàng)建新進(jìn)程時(shí),只需要向zygote進(jìn)程發(fā)出請(qǐng)求,zygote進(jìn)程監(jiān)聽到請(qǐng)求后, 會(huì)相應(yīng)地"分裂"出新的進(jìn)程,于是這個(gè)新進(jìn)程在出生之時(shí),就先天具有了自己的Dalvik 虛擬機(jī)及系統(tǒng)資源。

zygote服務(wù)在init.zygote32.rc文件中描述如下:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server

class main

socket zygote stream 660 root system

onrestart write /sys/android_power/request_state wake

onrestart write /sys/power/state on

onrestart restart media

onrestart restart netd

init進(jìn)程在運(yùn)行app_process時(shí)根據(jù)如下規(guī)則傳遞參數(shù),app_process參數(shù)形式如下:

app_process [java-options] cmd-dir start-class-name [options]

(1)[java-options] : 傳遞給虛擬機(jī)的選項(xiàng),必須以"-"開始

(2)cmd-dir : 所要運(yùn)行的進(jìn)程所在的目錄

(3)start-class-name : 要在虛擬機(jī)中運(yùn)行的類的名稱。app_process會(huì)將制定的類加載到 虛擬機(jī)中,而后調(diào)用類的main()方法。

(4)[options] : 要傳遞給類的選項(xiàng)

根據(jù)參數(shù)規(guī)則,可以知道-Xzygote是指要傳遞給VM的選項(xiàng)。"-Xzygote"選項(xiàng)用來區(qū)分要 在虛擬機(jī)中運(yùn)行的類是Zygote,還是在Zygote中運(yùn)行其他Android應(yīng)用程序,“--zygote”表示 加載com.android.internal.os.zygoteInit類。后一個(gè)參數(shù)"--start-system-server"作為選項(xiàng)傳 遞給生成的類,用于啟動(dòng)運(yùn)行系統(tǒng)服務(wù)器。

好了,了解完這些以后,我們來看看zygote的詳細(xì)實(shí)現(xiàn)。

二、zygote服務(wù)創(chuàng)建過程分析

通過前面的分析,我們知道zygote對(duì)應(yīng)的應(yīng)用程序是/system/bin/app_process,它對(duì)應(yīng)的源 代碼在framework\base\cmds\app_process\app_main.cpp文件中。

可以看到在運(yùn)行app_process應(yīng)用程序的時(shí)候,傳遞了"--zygote"參數(shù),所以這里會(huì)調(diào)用到runtime.start("com.android.internal.os.ZygoteInit","args");這句話的含義是加載com.android.internal.os.ZygoteInit類運(yùn)行。我們先來看 看runtime.start()函數(shù)的實(shí)現(xiàn)。

這段代碼主要用途如下如下:

(1)jni_invocation.Init(NULL)初始化jni接口

(2)startVM(&mJavaVM,&env)啟動(dòng)Dalvik虛擬機(jī)

(3)startReg(env)注冊(cè)jni函數(shù)接口,方便Java世界與C/C++世界溝通

(4)FindClass(slashClassName)通過根據(jù)類名解析出來的路徑查找指定的類

(5)env->GetStaticMethodID()獲取指定指定類的main函數(shù)接口

(6)env->CallStaticVoidMethod()調(diào)用指定的函數(shù)接口

跋山涉水,終于構(gòu)造出了Java世界(AndroidRuntime---Dalvik虛擬機(jī)),接下來我們就開始在Java世界中加載第一個(gè)類:ZygoteInit運(yùn)行。

三、ZygoteInit類運(yùn)行過程分析

好了,至此我們從苦逼的C/C++世界進(jìn)入了高富帥的Java世界,下面我們來看看 ZygoteInit類所做的事情,它對(duì)應(yīng)的源代碼 在frameworks\base\core\java\com\android\internal\os\ZygoteInit.java中。

這段代碼的主要用途如下:

(1)registerZygoteSocket(socketName),這個(gè)函數(shù)用來綁定套接字,以便接收新Android應(yīng)用 程序的運(yùn)行請(qǐng)求。Zygote使用UDS(Unix Domain Socket),為了從接 收ActivityManagerService(AMS)發(fā)來的新Android應(yīng)用程序的運(yùn)行請(qǐng)求。

(2)preload()函數(shù)實(shí)現(xiàn)如下:

static void preload() {

Log.d(TAG, "begin preload"); preloadClasses(); //加載

preloadResources(); preloadOpenGL(); preloadSharedLibraries();

// Ask the WebViewFactory to do any initialization that must run in the zygote process,

// for memory sharing purposes. WebViewFactory.prepareWebViewInZygote(); Log.d(TAG, "end preload");

}

可以看到zygote進(jìn)程在運(yùn)行的過程中加載了應(yīng)用程序框架中的類、平臺(tái)資源(圖像、 XML信息、字符串等)預(yù)先加載到內(nèi)存中。新進(jìn)程直接使用這些類與資源,而不需要重 新加載他們,這大大加快了程序的執(zhí)行速度。

------------------------------------------------------------------------------------------------------------------------

加載應(yīng)用程序Framework中包含的資源 在Android應(yīng)用程序Framework中使用的字符串、顏色、圖像文件、音頻文件等都被 稱為資源。應(yīng)用程序不能直接訪問這些資源,需要通過Android開發(fā)工具自動(dòng)生成的 R類來訪問。通過R類可訪問的資源組成信息記錄在XML中。Android資源大致可以 分為兩大類,如下:

<1>Drawable 這類資源是指畫面、照片、圖標(biāo)等可在畫面中繪畫的資源。preloadResource會(huì)加載 按鈕圖片、按鈕組等基本主題圖像。Android應(yīng)用程序Framework中包含CheckBox、 Button、Editbox、Call等圖像文件。

<2>XML管理的資源

XML管理的資源有保存字符串的strings.xml、保存字符串?dāng)?shù)組的arrays.xml,以及保 存顏色值得colors.xml等。此外,動(dòng)畫、布局等資源也是由XML文件管理的。

------------------------------------------------------------------------------------------------------------------------

(3)startSystemServer(abiList,socketName)

創(chuàng)建了一個(gè)子進(jìn)程,然后在子進(jìn)程中加載"com.android.server.SystemServer"類運(yùn)行。下面 我們接著看看,它是如何運(yùn)行SystemServer類運(yùn)行的。

關(guān)閉了從父進(jìn)程那邊繼承過來的套接字文件描述符,然手調(diào)用了RuntimInit.zygoteInit()方法。這個(gè)方法在frameworks\base\core\java\com\android\internal\os\RuntimeInit.java文件中定義,我們來看看它的具體實(shí)現(xiàn)

通過Class.forName加載SystemServer類,然后通過cl.getMethod()方法獲取SystemServer類 的main方法。 在這里我們并沒有看到直接調(diào)用這個(gè)"main"方法,而是拋出了一個(gè)一個(gè)異常。通過注釋 我們可以知道,這個(gè)異常

終會(huì)被ZygtoeInit.main()函數(shù)捕獲。

我們來看看caller.run()方法的實(shí)現(xiàn)。

很簡(jiǎn)單啦,調(diào)用指定的方法。我們這里就是SystemServer類的main方法。嗯,至此SystemServer這個(gè)進(jìn)程就創(chuàng)建 成功了。創(chuàng)建子進(jìn)程成功后,我們的父進(jìn)程zygote從startSystemServer()函數(shù)返回后,會(huì) 調(diào)用runSelectLoop()方法。

從注釋中我們就可以知道,zygote進(jìn)程終一直在runSelectLoop函數(shù)工作。這個(gè)函數(shù) 終就會(huì)調(diào)用到C/C++層 的select函數(shù),探測(cè)socket文件描述附是否就緒。如果有,則說明ActivityManagerService向它發(fā)出了"啟動(dòng)新應(yīng)用進(jìn)程" 的命令,zygote進(jìn)程收到命令后,就會(huì)fork一個(gè)子進(jìn)程,然后在子進(jìn)程中拋出一個(gè) MethodAndArgsCaller異常。 終會(huì)被ZygoteInit.main()函數(shù)捕獲,然后調(diào)用call.run()方法,終調(diào)用需要運(yùn)行類 的main方法,這樣應(yīng)用程序就跑起來啦。

好了,下面我們畫一幅圖總結(jié)一下zygote進(jìn)程做的的事情:

四、SystemServer服務(wù)分析

通過前面的分析我們知道SystemServer是zygote進(jìn)程孵化出來的第一個(gè)進(jìn)程,它在 Android的運(yùn)行環(huán)境中扮演了"神經(jīng)中樞"的作用,APK應(yīng)用中能夠直接交互的大部分系統(tǒng) 服務(wù)都在該進(jìn)程中運(yùn)行,常見的比如WindowManagerServer(WMS)、 ActivityManagerSystemService(AMS)、PackageManagerServer(PMS)等,這些系統(tǒng)服務(wù)都是 以一個(gè)線程的方式存在于SystemServer進(jìn)程中。所以SystemServer關(guān)系了整個(gè)Java世界 的生死存亡,如果SystemServer進(jìn)程異常退出,zygote進(jìn)程知道后就會(huì)"自殺",接著init 進(jìn)程重新啟動(dòng)zygote進(jìn)程,從而再次開啟Java世界。

下面我們簡(jiǎn)單分析一下SystemServer的運(yùn)行過程:

frameworks\base\services\java\com\android\server\SystemServer.java

從上述代碼中我們可以看到SystemServer中啟動(dòng)了Java世界中所需要的服務(wù),它分為核心 平臺(tái)服務(wù)與硬件服務(wù)

(1)核心平臺(tái)服務(wù)(Core Platform Service) 一般而言,核心平臺(tái)服務(wù)不會(huì)直接與Android應(yīng)用程序進(jìn)行交互,但它們是Android Framework運(yùn)行所必須的服務(wù),其包含的主要服務(wù)如下表所示:

(2)硬件服務(wù)(Hardware Service)

該服務(wù)提供了一系列的API,用戶控制底層硬件, 主要服務(wù)包含如下

五、監(jiān)聽zygote socket分析

ZygoteInit的main()函數(shù)在調(diào)用完startSystemServer()之后,就會(huì)調(diào)用runSelectLoop()函數(shù), 它的代碼如下:

frameworks\base\core\java\com\android\internal\os\ZygoteInit.java

這段代碼完成的功能如下: (1)通過selectReadable()函數(shù)探測(cè)是否有連接請(qǐng)求

(2)如果有則調(diào)用acceptCommandPeer()函數(shù),提取添加請(qǐng)求,并且把已連接的文件描述符 添加到文件描述符集合中

(3)如果有zygote socket中有數(shù)據(jù)到達(dá),則調(diào)用peers.get(index).runOnce()函數(shù)。

runOnce()函數(shù)的實(shí)現(xiàn)代碼如下: frameworks\base\core\java\com\android\internal\os\ZygoteConnection.java:

這段代碼的功能如下: (1)調(diào)用Zygote.forkAndSpecialize()函數(shù)創(chuàng)建子進(jìn)程 (2)調(diào)用handleChildProc()函數(shù)

可以看到這個(gè)函數(shù)終調(diào)用了ZygoteInit.invokeStaticMain()函數(shù),這個(gè)函數(shù)間接拋出特殊 的MethodAndArgsCaller異常,只不過此時(shí)拋出的異常攜帶的類名為ActivityThread。

注意:ActivityThread類在運(yùn)行的時(shí)候,也標(biāo)示著我們APK應(yīng)用程序的運(yùn)行,它就是 APK應(yīng)用程序的入口哦!等等,Android APP應(yīng)用程序的入口不是onCreate()方法嗎?呵呵!真正的入口是ActivityThread類, 這個(gè)類在運(yùn)行的時(shí)候會(huì)間接調(diào)用到相應(yīng)

類的onCreate()方法。

上一篇:如何實(shí)現(xiàn)Arm處理器ICache的測(cè)試

下一篇:Android.mk分析

熱點(diǎn)文章推薦
華清學(xué)員就業(yè)榜單
高薪學(xué)員經(jīng)驗(yàn)分享
熱點(diǎn)新聞推薦
前臺(tái)專線:010-82525158 企業(yè)培訓(xùn)洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠(yuǎn)見科技集團(tuán)有限公司 版權(quán)所有 ,京ICP備16055225號(hào)-5,京公海網(wǎng)安備11010802025203號(hào)

回到頂部