1. 程式人生 > >從原始碼分析 Android dexClassLoader 載入機制原理

從原始碼分析 Android dexClassLoader 載入機制原理

int dvmRawDexFileOpen(const char* fileName, const char* odexOutputName,
    RawDexFile** ppRawDexFile, bool isBootstrap)
{
    .................
    dexFd = open(fileName, O_RDONLY);
    if (dexFd < 0) goto bail;

    /* If we fork/exec into dexopt, don't let it inherit the open fd. */
    dvmSetCloseOnExec(
dexFd);

    //校驗前8個位元組的magic是否正確,然後把校驗和儲存到adler32
    if (verifyMagicAndGetAdler32(dexFd, &adler32) < 0) {
        ALOGE("Error with header for %s", fileName);
        goto bail;
    }
    //得到檔案修改時間以及檔案大小
   if (getModTimeAndSize(dexFd, &modTime, &fileSize) < 0) {
        ALOGE(
"Error with stat for %s", fileName);
        goto bail;
    }
    .................
    //呼叫函式dexOptCreateEmptyHeader,構造了一個DexOptHeader結構體,寫入fd並返回
    optFd = dvmOpenCachedDexFile(fileName, cachedName, modTime,
        adler32, isBootstrap, &newFile, /*createIfMissing=*/true);

    if (optFd <
 0) {
        ALOGI("Unable to open or create cache for %s (%s)",
                fileName, cachedName);
        goto bail;
    }
    locked = true;

       //如果成功生了opt頭
    if (newFile) {
        u8 startWhen, copyWhen, endWhen;
        bool result;
       off_t dexOffset;

        dexOffset = lseek(optFd, 0, SEEK_CUR);
        result = (dexOffset > 0);

        if (result) {
            startWhen = dvmGetRelativeTimeUsec();
            // 將dex檔案中的內容寫入檔案的當前位置,也就是從dexOffset的偏移處開始寫
            result = copyFileToFile(optFd, dexFd, fileSize) == 0;
            copyWhen = dvmGetRelativeTimeUsec();
        }

        if (result) {
            //對dex檔案進行優化
            result = dvmOptimizeDexFile(optFd, dexOffset, fileSize,
                fileName, modTime, adler32, isBootstrap);
        }

        if (!result) {
            ALOGE("Unable to extract+optimize DEX from '%s'", fileName);
            goto bail;
        }

        endWhen = dvmGetRelativeTimeUsec();
        ALOGD("DEX prep '%s': copy in %dms, rewrite %dms",
            fileName,
            (int) (copyWhen - startWhen) / 1000,
            (int) (endWhen - copyWhen) / 1000);
    }

     //dvmDexFileOpenFromFd這個函式最主要在這裡幹了兩件事情
     // 1.將優化後得dex檔案(也就是odex檔案)通過mmap對映到記憶體中,並通過mprotect修改它的對映記憶體為只讀許可權
     // 2.將對映為只讀的這塊dex資料中的內容全部提取到DexFile這個資料結構中去
    if (dvmDexFileOpenFromFd(optFd, &pDvmDex) != 0) {
        ALOGI("Unable to map cached %s", fileName);
        goto bail;
    }

    if (locked) {
        /* unlock the fd */
       if (!dvmUnlockCachedDexFile(optFd)) {
            /* uh oh -- this process needs to exit or we'll wedge the system */
            ALOGE("Unable to unlock DEX file");
            goto bail;
        }
        locked = false;
    }

    ALOGV("Successfully opened '%s'", fileName);
    //填充結構體 RawDexFile
    *ppRawDexFile = (RawDexFile*) calloc(1, sizeof(RawDexFile));
    (*ppRawDexFile)->cacheFileName = cachedName;
   (*ppRawDexFile)->pDvmDex = pDvmDex;
    cachedName = NULL;      // don't free it below
    result = 0;

bail:
    free(cachedName);
    if (dexFd >= 0) {
        close(dexFd);
    }
    if (optFd >= 0) {
        if (locked)
            (void) dvmUnlockCachedDexFile(optFd);
        close(optFd);
    }
    return result;
}

相關推薦

原始碼分析 Android dexClassLoader 載入機制原理

int dvmRawDexFileOpen(const char* fileName, const char* odexOutputName,     RawDexFile** ppRawDexFile, bool isBootstrap) {     .................     de

原始碼分析AsyncTask執行流程和原理

本篇文章將從大體上分析AsyncTask的原理,不會涉及過多的細節。AsyncTask現在已經不再流行了,但作為學習還是要了解下。 使用方法 下面是AsyncTask一般的使用場景,相信使用過AsyncTask的人都不會覺得陌生 class MyAsyncTask ex

原始碼分析 Android Button 點選效果

Android 點選效果 我們平時在開發過程中都可能注意到,我們寫的預設的 Button 都是有點選效果的,而且大小也有預設規定的,而 TextView 就沒有。就想下面的圖片一樣。 是有預設效果的。通過檢視 Button 的原始碼我們看到: 每個 b

原始碼分析Spring處理property-placeholder原理

一、如何在Spring中將屬性檔案配置內容載入到環境中1.1、在Spring的XML配置檔案中配置<context:property-placeholder/>,由於<context:property-placeholder/>名稱空間為http://

Spark原始碼分析之Master註冊機制原理

一 Worker向Master註冊 1.1 Worker啟動,呼叫registerWithMaster,向Master註冊 當worker啟動的時候,會呼叫registerWithMaster方法

[五]類載入機制雙親委派機制 底層程式碼實現原理 原始碼分析 java類載入雙親委派機制是如何實現的

Launcher啟動類 本文是雙親委派機制的原始碼分析部分,類載入機制中的雙親委派模型對於jvm的穩定執行是非常重要的 不過原始碼其實比較簡單,接下來簡單介紹一下 我們先從啟動類說起 有一個Launcher類   sun.misc.Launcher; 仔細看下這簡

【朝花夕拾】Android自定義View篇之(六)Android事件分發機制(中)原始碼分析事件分發邏輯及經常遇到的一些“詭異”現象

前言        轉載請註明,轉自【https://www.cnblogs.com/andy-songwei/p/11039252.html】謝謝!        在上一篇文章【【朝花夕拾】Android自定義View篇之(

Android原始碼分析 - View事件分發機制

事件分發物件 (1)所有 Touch 事件都被封裝成了 MotionEvent 物件,包括 Touch 的位置、時間、歷史記錄以及第幾個手指(多指觸控)等。 (2)事件型別分為 ACTION_DOWN, ACTION_UP,ACTION_MOVE,ACTION_POINTER_D

原始碼分析HashMap實現原理

HashMap 基於雜湊表的 Map 介面的實現。此實現提供所有可選的對映操作,並允許使用 null 值和 null 鍵。(除了不同步和允許使用 null 之外,HashMap 類與 Hashtable 大致相同。)此類不保證對映的順序,特別是它不保證該順序恆久不變。另外,HashMap是非

【Java面試題】之類載入面試題分析Java類載入機制

 “載入”(Loading)階段是“類載入”(Class Loading)過程的第一個階段,在此階段,虛擬機器需要完成以下三件事情:        1、 通過一個類的全限定名來獲取定義此類的二進位制位元組流。        2、 將這個位元組流所代表的靜態儲存結構轉化為方法區的執行時資料結

原始碼Android】03Android MessageQueue訊息迴圈處理機制(epoll實現)

1 enqueueMessage handler傳送一條訊息 mHandler.sendEmptyMessage(1);經過層層呼叫,進入到sendMessageAtTime函式塊,最後呼叫到enqueueMessageHandler.java public bool

Android開發-原始碼分析Fragment巢狀PagerAdapter生命週期,解決重建問題

介紹 眾所周知在Android開發中Fragment的生命週期非常複雜,複雜得甚至讓Square公司提出了我為什麼主張反對使用Android Fragment轉而提倡使用自定義View組合替代Fragment。但是沒辦法公司專案還是使用了很多Fragment巢狀

Master原理剖析與原始碼分析:資源排程機制原始碼分析(schedule(),兩種資源排程演算法)

1、主備切換機制原理剖析與原始碼分析 2、註冊機制原理剖析與原始碼分析 3、狀態改變處理機制原始碼分析 4、資源排程機制原始碼分析(schedule(),兩種資源排程演算法) * Dri

Android自定義ActionBar背景顏色(原始碼分析

Android自定義ActionBar背景顏色 修改前後效果圖:   在style.xml里加一行程式碼搞定 <!-- Base application theme. --> <style name="AppTheme" parent="

Android 原始碼分析Bitmap和BitmapFactory常用API

Bitmap recycle() 呼叫nativeRecycle()釋放該bitmap分配的native物件,清除對畫素資料的引用。不會同步的釋放畫素資料,只是簡單的允許bitmap在沒有其他引用時被垃圾回收。此bitmap被標記為dead,意味著呼叫get

React-原始碼分析React Fiber工作原理

為什麼要重寫React React16 以前 React16 以前,對virtural dom的更新和渲染是同步的。就是當一次更新或者一次載入開始以後,diff virtual dom並且渲染的過程是一口氣完成的。如果元件層級比較深,相應的堆疊也

Deno原理詳解,讓我們一起原始碼分析開始

Node之父ry:在“Node中的設計錯誤”演講中表示: 不允許將任意本地函式繫結至 V8 當中。 所有系統呼叫都將

自定義spring boot starter三部曲之三:原始碼分析spring.factories載入過程

本文是《自定義spring boot starter三部曲》系列的終篇,前文中我們開發了一個starter並做了驗證,發現關鍵點在於spring.factories的自動載入能力,讓應用只要依賴starter的jar包即可,今天我們來分析Spring和Spring boot原始碼,瞭解s

Dubbo 原始碼分析系列之三 —— 架構原理

1 核心功能 首先要了解Dubbo提供的三大核心功能: Remoting:遠端通訊 提供對多種NIO框架抽象封裝,包括“同步轉非同步”和“請求-響應”模式的資訊交換方式。 Cluster: 服務框架 提供基於介面方法的透明遠端過程呼叫,包括多協議支援,以及

【逆向工程】原始碼分析網站反爬蟲措施

       從事網頁爬蟲工作有兩年了,從最開始的新聞,bbs論壇,論文網站,到現在的全國企業信用資訊公示系統,無論是PC網頁,到手機移動APP,還是現在的支付寶微信小程式一直採集別人家網站上的資料,也算得上也是身經百戰。如今,領導安排我注意收集整理歸納一下反