當(dāng)你安裝一個(gè)APK包時(shí)杀饵,有沒有思考過此時(shí)你的手機(jī)做了哪些操作呢?做完這些操作后咙鞍,一個(gè)應(yīng)用就算在手機(jī)上安裝成功房官,進(jìn)而這個(gè)應(yīng)用就可以被運(yùn)行呢?下面我們來一步步的探討下续滋。
當(dāng)你點(diǎn)擊安裝后翰守,首先是APK中的AndroidManifest.xml
被解析,解析的內(nèi)容會(huì)被存儲(chǔ)到/data/system/packages.xml
和/data/system/packages.list
中疲酌。我們打開packages.list和packages.xml蜡峰,找到Demo應(yīng)用包名了袁,如下圖
packages.list中指名了該應(yīng)用默認(rèn)存儲(chǔ)的位置/data/data/cn.hadcn.example
,packages.xml中包含了該應(yīng)用申請(qǐng)的權(quán)限湿颅、簽名和代碼所在位置等信息载绿,并且兩者都有一個(gè)userId為10060。之所以每個(gè)應(yīng)用都有一個(gè)userId油航,是因?yàn)锳ndroid在系統(tǒng)設(shè)計(jì)上把每個(gè)應(yīng)用當(dāng)作Linux系統(tǒng)上的一個(gè)用戶對(duì)待卢鹦,這樣就可以利用已有的Linux上用戶管理機(jī)制來設(shè)計(jì)Android應(yīng)用,比如應(yīng)用目錄劝堪,應(yīng)用權(quán)限,應(yīng)用進(jìn)程管理等揉稚。
做完以上操作秒啦,就相當(dāng)于應(yīng)用在系統(tǒng)注冊(cè)了,可以被系統(tǒng)識(shí)別搀玖。接下來就得保存應(yīng)用的執(zhí)行文件了余境,根據(jù)packages.xml
中指定的codePath
,創(chuàng)建一個(gè)目錄灌诅,apk會(huì)被命名成base.apk
并拷貝到此芳来,其中l(wèi)ib目錄用來存放native庫。如下圖所示
注:目錄是由 包名-1 組成猜拾,有時(shí)候此處是 -2即舌。這是為了升級(jí)使用,升級(jí)時(shí)會(huì)新創(chuàng)建一個(gè)-1 或 -2的目錄挎袜,如果升級(jí)成功顽聂,則刪除原目錄并更改packages.xml中codePath到新目錄
此時(shí)應(yīng)用就可以運(yùn)行了,但如果每次應(yīng)用運(yùn)行還得去base.apk中取dex文件盯仪,效率就太低了紊搪。為了提升效率,Android系統(tǒng)在應(yīng)用安裝時(shí)還會(huì)做些優(yōu)化操作全景,把所有可運(yùn)行的dex文件單獨(dú)提取放在一塊并做些優(yōu)化耀石。在Dalvik模式下,會(huì)使用dexopt把base.apk中的dex文件優(yōu)化為odex爸黄,存儲(chǔ)在/data/dalvik-cache
中滞伟,如果是ART模式,則會(huì)使用dex2oat優(yōu)化成oat文件也存儲(chǔ)在該目錄下馆纳,并且文件名一樣诗良,但文件大小會(huì)大很多,因?yàn)锳RT模式會(huì)在安裝時(shí)把dex優(yōu)化為機(jī)器碼鲁驶,所以在ART模式下的應(yīng)用運(yùn)行更快鉴裹,但apk安裝速度相對(duì)Dalvik模式下變慢,并且會(huì)占用更多的ROM。
優(yōu)化后的dex文件被載入到虛擬機(jī)中就可以運(yùn)行径荔。
參考
http://stackoverflow.com/questions/12442979/android-understanding-the-apk-installation-process
作者簡(jiǎn)介
彭濤(@彭濤me) 致力于讓技術(shù)變得易懂且有趣
個(gè)人博客:http://pengtao.me, GitHub地址:https://github.com/CPPAlien