1. 程式人生 > >Android中dex檔案的載入與優化流程

Android中dex檔案的載入與優化流程

目錄

1、dex檔案分析

邏輯上,可以把dex檔案分成3個區,標頭檔案、索引區和資料區。索引區的ids字尾為identifiers的縮寫。


header

dex檔案裡的header。除了描述.dex檔案的檔案資訊外,還有檔案裡其他各個區域的索引。


(1)           magic value,這8個位元組一般是常量,為了使.dex檔案能夠被識別出來,它必須出現在.dex檔案的最開頭的位置。

(2)           checksum和signature.檔案校驗碼,使用alder32演算法校驗檔案出去maigc,checksum外餘下的所有檔案區域,用於校驗檔案錯誤。Signature,使用SHA-1演算法hash除去magic,checksum和signature外餘下的所有檔案區域。

(3)           file_size:Dex檔案的大小。

其餘的屬性,因為在加固中沒有用到。這裡就不對它們進行過多解釋。

2、odex檔案

odex是OptimizedDEX的縮寫,表示經過優化的dex檔案。存放在/data/dalvik-cache目錄下。由於Android程式的apk檔案為zip壓縮包格式,Dalvik虛擬機器每次載入它們時需要從apk中讀取classes.dex檔案,這樣會耗費很多cpu時間,而採用odex方式優化的dex檔案,已經包含了載入dex必須的依賴庫檔案列表,Dalvik虛擬機器只需檢測並載入所需的依賴庫即可執行相應的dex檔案,這大大縮短了讀取dex檔案所需的時間。

不過,這個優化過程會根據不同裝置上Dalvik虛擬機器的版本、Framework庫的不同等因素而不同。在一臺裝置上被優化過的ODEX檔案,拷貝到另一臺裝置上不一定能夠執行。

2.1、odex檔案結構

Odex檔案的結構可以理解為dex檔案的一個超集。它的結構如下圖所示,odex檔案在dex檔案頭部添加了一些資料,然後在dex檔案尾部添加了dex檔案的依賴庫以及一些輔助資料。



Dalvik虛擬機器將dex檔案對映到記憶體中後是Dalvik格式,在Android系統原始碼的dalvik/libdex/DexFile.h檔案中它的定義如下。

DexFile結構中存入的多為其他結構的指標。DexFile最前面的DexOptHeader就是odex的頭,DexLink以下的部分被成為auxillary section,即輔助資料段,它記錄了dex檔案被優化後新增的一些資訊。然而,DexFile結構描述的是載入進記憶體的資料結構,還有一些資料是不會載入進記憶體的,經過分析,odex檔案結構定義整理如下.


Struct ODEXFile{

           DexOptHeader             header;    /*odex檔案頭*/

           DEXFile                          dexfile;  /*dex檔案*/

           Dependences              deps;        /*依賴庫列表*/

           ChunkDexClassLookup    lookup;     /*類查詢結構*/

           ChunkRegisterMapPool          mappool; /*對映池*/

           ChunkEnd                            end;    /*結束標誌*/

};

2.2、odex檔案結構分析

         ODEXFile的檔案頭DexOptHeader在DexFile.h檔案中定義如下.

struct DexOptHeader{

         u1  magic[8];                  /*odex版本標識 */

         u4  dexOffset;            /* dex檔案頭偏移*/

         u4  dexLength;      /* dex檔案總長度*/

         u4  depsOffset;      /*odex依賴庫列表偏移*/

         u4  depsLength;     /*依賴庫列表總長度*/

         u4  optOffset;       /*輔助資料偏移*/

         u4  optLength;       /*輔助資料總長度*/

         u4  flags ;                          /*標誌*/

         u4  checksum;        /*依賴庫與輔助資料的校驗和*/

};

3、dex檔案的驗證與優化

Android提供了一個專門驗證與優化dex檔案的工具dexopt。其原始碼位於Android系統原始碼的dalvik/dexopt目錄下,Dalvik虛擬機器在載入一個dex檔案時,通過指定的驗證與優化選項來呼叫dexopt進行相應的驗證與優化操作。

         dexopt的主程式為OptMain.cpp,其中處理apk/jar/zip檔案中的classes.dex的函式為extractAndProcessZip(),extractAndProcessZip()首先通過dexZipFindEntry()函式檢查目標檔案中是否擁有class.dex,如果沒有就失敗返回,成功的話就呼叫dexZipGetEntryInfo()函式來讀取classes.dex的時間戳與crc校驗值,如果這一步沒有問題,接著呼叫dexZipExtractEntryTo-File()函式釋放classes.dex為快取檔案,然後開始解析傳遞過來的驗證與優化選項,驗證選項使用“v=”指出,優化選項使用“o=”指出。所有的預備工作都做完後,呼叫dvmPrepForDexOpt()函式啟動一個虛擬機器程序,在這個函式中,優化選項dexOptMode與驗證選項varifyMode被傳遞到了全域性DvmGlobals結構gDvm的dexOptMode與classVerifyMode欄位中。這時候所有的初始化工作已經完成,dexopt呼叫dvmContinueOptimization()函式開始真正的驗證和優化工作。

         dvmContinueOptimization()函式的呼叫鏈比較長。首先從OptMain.cpp轉移到、dalvik/vm/analysis/DexPrepare.cpp,因為這裡有dvmContinueOptimization()函式的實現。函式首先對dex檔案做簡單的檢查,確保傳遞進來的目標檔案屬於dex或odex,接著呼叫mmap()函式將整個檔案對映到記憶體中,然後根據gDvm的dexOptMode與classVerifyMode欄位來設定doVarify與doOpt兩個布林值,接著呼叫rewriteDex()函式來重寫dex檔案,這裡的重寫內容包括字元調整、結構重新對齊、類驗證資訊以及輔助資料。rewriteDex()函式呼叫dexSwapAndVerify()調整位元組序,接著呼叫dvmDexFileOpenPartial()建立DexFile結構,dvmDexFileOpenPartial()函式的實現在Android系統原始碼dalvik/vm/DvmDex.cpp檔案中,該函式呼叫dexFileParse()函式解析dex檔案,dexFileParse()函式讀取dex檔案的頭部,並根據需要呼叫驗證dexComputeChecksum()函式或呼叫dexComputeOptChecksum()函式來驗證dex或odex檔案愛你頭的checksum與signature欄位。

         接著回到DvmDex.cpp檔案繼續看程式碼,當驗證成功後,dvmDexFileOpenPartial()函式呼叫allocateAuxStructures()函式設定DexFile結構輔助資料的相關欄位,最後執行完後返回到rewriteDex()函式。rewriteDex()接下來呼叫loadAllClasses()載入dex檔案中所有的類,如果這一步失敗了,程式等不到後面的優化與驗證就退出了,如果沒有錯誤發生,會呼叫verifyAndOptimizeClasses()函式進行真正的驗證工作,這個函式會呼叫verifyAndOptimizeClass()函式來優化與驗證具體的類,而verifyAndOptimizeClass()函式會細分這些工作,呼叫dvmVerifyClass()函式進行驗證,再呼叫dvmOptimizeClass()函式進行優化。

         dvmVerifyClass()函式的實現程式碼位於Android系統原始碼的dalvik/vm/analysis/DexVerify.cpp檔案中。這個函式呼叫verifyMethod()函式對類的所有直接方法與虛方法進行驗證,verifyMethod()函式具體的工作是先呼叫verifyInstructions()函式來驗證方法中的指令及其資料的正確性,再呼叫dvmVerifyCodeFlow()函式來驗證程式碼流的正確性。

         dvmOptimizeClass()函式的實現程式碼位於Android系統原始碼的dalvik/vm/analysis/Optimize.cpp檔案愛你中。這個函式呼叫optimizeMethod()函式對類的所有直接方法與虛方法進行優化,優化的主要工作是進行“指令替換”,替換原則的優先順序為“volatile”替換-正確性替換-高效能替換。比如指令iget-wide會根據優先順序替換為“volatile”形式的iget-wide-volatile,而不是高效能的iget-wide-quick.

         rewriteDex函式返回後,會再次呼叫dvmDexFileOpenPartial()來驗證odex檔案,接著呼叫dvmGenerateRegisterMaps()函式來填充輔助資料區結構,填充結構完成後,接下來呼叫updateChecksum()函式重寫dex檔案愛你的checksum值,再往下就是writeDependencies()與writeOptData()了。

3.2 dex檔案優化載入流程圖

 

相關推薦

Androiddex檔案載入優化流程

目錄 1、dex檔案分析 邏輯上,可以把dex檔案分成3個區,標頭檔案、索引區和資料區。索引區的ids字尾為identifiers的縮寫。 header dex檔案裡的header。除了描述.dex檔案的檔案資訊外,還有檔案裡其他各個區域的索引。 (

Android學習記錄(1)—AndroidXML檔案的序列化生成解析

xml檔案是非常常用的,在android中json和xml是非常常用的兩種封裝資料的形式,從伺服器中獲取資料也經常是這兩種形式的,所以學會生成和解析xml和json是非常有用的,json相對來說是比較簡單的,咱不做介紹了,這裡給大家講一下xml的序列化生成和解析。不廢話了,

androidimage檔案的壓縮解壓縮

我們將android原始碼進行編譯之後,會在out/target/product/<product-name>/目錄下生成幾個image檔案:system.img,recovery.img,userdata.img等,將這些image檔案連同一些bin檔案燒寫到

淺談Android的非同步載入之ListView圖片的快取及優化

     隔了很久沒寫部落格,現在必須快速脈動回來。今天我還是接著上一個多執行緒中的非同步載入系列中的最後一個使用非同步載入實現ListView中的圖片快取及其優化。具體來說這次是一個綜合Demo.但是個人覺得裡面還算有點價值的就是裡面的圖片的快取的實現。因為老實說它確實能

Androidapk動態載入技術研究(2)android插件化及實現

name creat package path iss fontsize 調用 dex con 了解了android中類載入的前期知識點後,來看看android中DexClassLoader詳細的實現 詳細載入流程例如以下: 宿主程序會到文件系統比

Androiddp、dpipx的關系

聯系 vga 公式 矩形 鏈接 相同 針對 來源 商業 轉自知乎用戶的回答: 1. dpi是dot per inch,每英寸多少點,ppi是 Pixel per inch,每英寸像素數,針對顯示器的設計時,dpi=ppi。ppi計算方法是長寬各自平方之和開方,除以對角線長

vue的圖片載入顯示預設圖片

  原部落格地址:https://www.cnblogs.com/xulei1992/p/6558294.html     <div class="content-show-img">  <div class="show-img">    <img cl

ELF檔案載入動態連結(二)

GOT應該儲存的是puts函式的絕對虛地址,這裡為什麼儲存的卻是[email protected]的第二條指令呢? 原來“直譯器”將動態庫載入記憶體後,並沒有直接將函式地址更新到GOT表中,而是在函式第一次被呼叫時,才會進行函式地址的重定位,這樣做的好處是可以加快程式載入速度,尤其對大型程式來說。有

ELF檔案載入動態連結(一)

關於ELF檔案的詳細介紹,推薦閱讀: ELF檔案格式分析 —— 滕啟明。ELF檔案由ELF頭部、程式頭部表、節區頭部表以及節區4部分組成。   通過objdump工具和readelf工具,可以觀察ELF檔案詳細資訊。 ELF檔案載入過程分析 從編譯、連結和執行的角度,應用程

Android初試--Android檔案操作之SDcard操作(2)

SDCARD:通俗的說,就像外接硬碟。 在模擬器中使用SDCard,你需要先建立一張SDCard卡(當然不是真的SDCard,只是映象檔案)。建立SDCard可以在Eclipse建立模擬器時隨同建立,也可以使用DOS命令進行建立,在DOS視窗中進入android SDK安裝路徑的tools

Android初試--Android檔案操作之ROM操作(1)

RAM(Random Access Memory)隨機儲存器,在手機中稱為執行記憶體。通俗的說,就像電腦的記憶體。在斷電以後儲存在上面的資料會自動消失。 ROM(Read-Only Memory)只讀儲存器,存放手機韌體程式碼的儲存器,比如手機的作業系統、一些應用程式如遊戲等。通俗的說,就

Android的so檔案載入機制詳解

今日科技快訊 10月30日,小米集團跌超4%,再創上市以來新低,市值下破2600億港元關口。此前,財政部發布的《2018年會計資訊質量檢查公告》顯示,在2017年度會計執法檢查中發現,部分企業跨境轉移利潤、逃避繳納稅收等問題比較突出。在被點名的網際網路企業中,就包括

Node.jsfs檔案系統-檔案file相關;

1.首先引入fs檔案模組; //讀取檔案; fs.readFile(path[, options], callback)  path:檔名; options:檔案讀取方式; callback:回撥函式;回撥函式有兩個引數err data  其中data是檔案的

Android的執行緒執行緒池

執行緒與執行緒池 概括 執行緒分為主執行緒和子執行緒. 主執行緒主要是用來處理和介面相關的事情, 子執行緒主要是用來做耗時的操作,比如 載入遠端資料,資料庫操作等。 在android 中,處理直接使用 Thread以外。 android 還提供了很多類似執行緒的操作便於我們

Android 的 so 檔案載入機制

最近碰到一些 so 檔案問題,順便將相關知識點梳理一下。 提問 本文的結論是跟著 System.loadlibrary() 一層層原始碼走進去,個人對其的理解所整理的,那麼開始看原始碼之前,先來提幾個問題: Q1:你知道 so 檔案的載入流程嗎? Q2:裝置存放 so 的路徑有 system/lib,

liunx系統檔案壓縮解壓

zip格式 壓縮: zip -r [目標檔名].zip [原檔案/目錄名] 解壓: unzip [原檔名].zip 注:-r引數代表遞迴 tar格式(該格式僅僅打包,不壓縮) 打包:tar -cvf [目標檔名].tar [原檔名/目錄名] 解包:tar -xvf [原檔名]

androidjson檔案的讀取,並用gson轉換成jsonobject,jsonarray

1.手機儲存卡中json檔案的讀取,返回String //從手機儲存卡路徑下解析json,並返回String public static String getFileFromSD(String path) { String result = ""; try { FileInpu

OpenCV原始影象載入儲存壓縮技巧

載入影象 OpenCV中關於影象讀寫有兩個函式imread與imwrite,imread載入的時候支援灰度影象、彩色影象、原始影象載入,預設情況下通過imread載入的影象都是三通道的BGR彩色影象。 但是實際上OpenCV支援載入任意通道的影象,首先來仔細再看一下imread函式 Mat&

Android的模組(module)裝置(device)

轉自  https://blog.csdn.net/a345017062/article/details/6423866   以backlight這種裝置為例來說明一下Android系統中模組與裝置的關係。Android中的backlight、keyboard等多個裝置都

Hibernate的延遲載入機制&&在實際應用,延遲載入Session關閉的矛盾是如何處理的?

Hibernate的延遲載入機制&&在實際應用中,延遲載入與Session關閉的矛盾是如何處理的? 延遲載入就是並不是在讀取的時候就把資料載入進來,而是等到使用時再載入。Hibernate使用了虛擬代理機制實現延遲載入,我們使用Session的load()方法載