最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android 中的類文件和類加載器詳情

 更新時間:2022年06月04日 10:39:45   作者:? rEd_?  ?  
這篇文章主要介紹了Android 中的類文件和類加載器詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下

一、Java中的類加載器

首先花點(diǎn)時間回顧一下Java中的三種類加載器:

  • BootStrap ClassLoader 啟動類加載器,它是實現(xiàn)自C/C++的類加載器,用于加載JDK的核心類庫,例如java.lang、java.util等系統(tǒng)類。JVM的啟動需要通過BootStrap ClassLoader來創(chuàng)建一個初始類來完成。
  • Extensions ClassLoader 擴(kuò)展類加載器,ExtClassLoader,它用于加載一些系統(tǒng)之外的額外功能。
  • Application ClassLoader 應(yīng)用類加載器,也稱作系統(tǒng)類加載器,它可以通過getSystemClassLoader拿到,也可以稱為系統(tǒng)類加載器。
  • Custom ClassLoader 自定義類加載器,我們可以通過繼承java.lang.ClassLoader類來實現(xiàn)自己的類加載器,注意,ExtClassLoader和AppClassLoader也是繼承自java.lang.ClassLoader類的。

總體的加載關(guān)系是:null->ExtClassloader->AppClassLoader,需要注意的是,BootStrap ClassLoader無法在Java中通過.class.getClassLoader()訪問它的父加載器。

同時,這只代表加載關(guān)系,而不代表繼承關(guān)系,ClassLoader的繼承關(guān)系如下:

其中:

  • ClassLoader本身是一個抽象類,定義了主要的一些功能。
  • SecureClassLoader擴(kuò)展實現(xiàn)了ClassLoader方面加入權(quán)限方面的功能,加強(qiáng)了ClassLoader的安全性。
  • URLClassLoader通過URL路徑,從Jar文件和文件夾下加載類和資源。
  • ExtClassLoader和AppClassLoader,本身都是Launcher應(yīng)用的內(nèi)部類,Launcher是Java虛擬機(jī)的入口應(yīng)用,二者都在Launcher中初始化;

雙親委派機(jī)制,大致意思就是當(dāng)一個類加載器去加載某個類時,會優(yōu)先委托給父加載器去進(jìn)行加載,而不是自己加載。這樣能夠有效地保護(hù)加載類的安全性,比如我們希望加載一個java.lang.String類,在雙親委派機(jī)制下,我們就會優(yōu)先由父類進(jìn)行加載,而不是我們自己的類加載器去做加載,父類加載器會從指定的,安全的目錄下查找String類。如果是我們自己的類加載器中加載該類那么可能會出現(xiàn)一些安全方面的問題。換句話說,你自己定義的java.lang.String類是無法被加載的。當(dāng)然,這個前提是,你得遵循雙親委派機(jī)制,如果你重新寫個類加載器,自定義了loadClass并且不遵循雙親委派機(jī)制,那么雙親委派機(jī)制就被打破了。這也是為什么,JVM認(rèn)為兩個類相等不僅僅要類名相等,而且要類加載器相等才是同一個類。

二、Android中的類加載器

區(qū)別于標(biāo)準(zhǔn)JVM以Class文件為輸入的字節(jié)碼文件,Android虛擬機(jī)采用更為緊湊的Dex文件作為輸入文件,無論是Dalvik VM還是ART VM。這樣一來,類加載器自然也會有所改變。

Android中的類加載器類型被分為兩類:

  • 系統(tǒng)類加載器:PathClassLoader、DexClassLoader、BootClassLoader
  • 自定義類加載器

2.1 BootClassLoader

Android 系統(tǒng)啟動時,會使用BootClassLoader來加載常用的類,與SDK中的BootStrap ClassLoader不同的是,它本身不是由C/C++實現(xiàn)的, 而是采用Java實現(xiàn)的,它是ClassLoader的內(nèi)部類,繼承自ClassLoader,本身是一個單例類。應(yīng)用中無法直接訪問到BootClassLoader。

BootClassLoader是在ZygoteInit的入口方法中,間接調(diào)用了preloadClasses方法中,進(jìn)行創(chuàng)建的,Android在/framework/base/preloaded-classes中封裝了一系列的預(yù)加載類的目錄,一些常用類,例如:ContextImpl、Fragment、Dialog等等都在列。預(yù)加載之后,應(yīng)用程序啟動時,就不用額外去做加載了。

2.2 PathClassLoader

PathClassLoader它通常被系統(tǒng)用來加載Apk中自帶的Dex文件,它的構(gòu)造函數(shù)中少了一個參數(shù):optimizedDirectory,這是因為PathClassLoader定義了默認(rèn)的optimizedDirectory參數(shù):/data/dalvik-cache/,因此,我們無法自定義Dex文件的解壓路徑,所以我們加載類時,一般都使用DexClassLoader。

PathClassLoader是Zygote進(jìn)程在fork SystemServer進(jìn)程時創(chuàng)建的,當(dāng)Zygote進(jìn)程在新創(chuàng)建SystemServer時,通過調(diào)用forkSystemServer方法時,會調(diào)用到handleSystemServerProcess(),然后調(diào)用createPathClassLoader()去創(chuàng)建PathClassLoader。

2.3 DexClassLoader

可以在磁盤中加載.dex或者是.apk文件,但是本質(zhì)上都是加載屬于Android 的字節(jié)碼文件:Dex文件。

它的構(gòu)造方法有四個參數(shù):

  • dexPath:相關(guān)的文件路徑;支持多個路徑,使用「:」分割
  • optimizedDirectory:Dex文件解壓后的文件存儲路徑,一般情況下使用當(dāng)前文件的私有路徑。

"this parameter is deprecated and has no effect since API level 26."

注意:optimizedDirectory參數(shù)在API26之后被廢棄了

  • librarySearchPath:包含C/C++庫的路徑集合,可以為null
  • parent:父加載器

我們通常在App啟動時,我們通常使用DexClassLoader動態(tài)加載Dex的方式來實現(xiàn)應(yīng)用程序Java代碼層面的熱修復(fù)。

2.4 InMemoryDexClassLoader

Android8.0 中新增的用于加載內(nèi)存中的類加載器。和PathClassLoader、DexClassLoader一樣,都是BaseDexClassLoader的實現(xiàn)類。

三、Dex文件

3.1 Android內(nèi)存中的Dex文件

BaseDexClassLoader有三個子類:DexClassLoader、PathClassLoader、InMemoryDexClassLoader,它們?nèi)齻€主要任務(wù)就是:加載外部的Dex文件,獲取其中定義的類信息。同樣,Android的類加載機(jī)制也遵循雙親委派機(jī)制

BaseDexClassLoader有一個特殊的結(jié)構(gòu):DexPathList類型的pathList ,它內(nèi)部維護(hù)了一個Element類型的數(shù)組,用來存儲被加載的Dex文件信息:

private Element[] dexElements;

每當(dāng)我們要使用一個類時,類加載器就會先檢索:DexPathList中的所有Dex文件,逐個遍歷,看看其中是否含有所需要的類:

Element內(nèi)部有一個對象:DexFile,在調(diào)用Element#findClass時,會按照如下規(guī)則去查找:

而最終,loadClassBinaryName會調(diào)用Native代碼在本地內(nèi)存上創(chuàng)建一個指向Dex文件的對象,這樣 ,我們知道Dex文件在內(nèi)存中的引用是類加載下的DexPathList中的一個個Element。

這個Element數(shù)組可以作為一個熱修復(fù)的接入點(diǎn),我們知道,類加載只會被加載一次,如果此時我們有多個Dex文件,那么Dex文件的引用在Element中會按照加載的順序排列,這樣一來,排在前面的Dex類中的Class就會被優(yōu)先加載,由此我們就可以將熱修復(fù)后重新生成的Patch.dexPatch.apk加載到用戶手機(jī)存儲空間當(dāng)中,然后自行使用DexPathClassLoader進(jìn)行加載,并通過反射,Hook掉PathClassLoader,將Patch.dex對應(yīng)的Element反射插入到其DexPathList當(dāng)中去。這樣一來,加載時就會優(yōu)先從Patch.dex中加載了,原理大致如下圖。修復(fù)后加載原先出錯的類ClassE將會從Patch.dex中優(yōu)先加載,而出錯的Class E由于類加載的特性,將不會被加載出來。

3.2 Dex文件的生成

我們所編寫的Java代碼,使用Java自帶的編譯器編譯完成之后默認(rèn)的輸出一定是.class文件,而在ART或者Dalvik虛擬機(jī)中需要輸入Dex文件,那么在其中必然存在Class -> Dex文件的過程。

該過程是由d8工具完成的,在我們的SDK目錄下:/Library/Android/sdk/build-tools/28.0.3,有非常多和我們Android 構(gòu)建相關(guān)的一些工具,例如aapt2工具會負(fù)責(zé)將res.xml中的文件在R.java中生成對應(yīng)的ID引用、負(fù)責(zé)將二進(jìn)制資源、資源表resources.arsc、classes.dex以及assets集成打包進(jìn)一個未簽名的.apk文件內(nèi)。

d8工具會將需要打包的.class文件、額外依賴的Jar文件一同參與編譯。比如我們需要對appt2下的一個MainActivity.class文件進(jìn)行編譯,那么我們可以在一個新項目中,點(diǎn)擊Android Studio的編譯或者上面的綠色小錘子,然后在:MyApplication2/app/build/intermediates/javac/debug/classes/com/red/myapplication 下我看到MainActicity.class文件,然后在該目錄下執(zhí)行如下的指令,注意,將MainActivity的AppcompatActivity換成Activity,因為前者是屬于AndroidX系列的的AAR包中的依賴,需要額外添加。

d8 aapt/MainActivity.class
 --lib /Library/Android/sdk/platforms/android-29/android.jar
 --output ./

其中,--lib指定了一些額外的依賴,因為MainActivity中會依賴android.jar中的一些文件(比如Activity類),完成后,我們就得到了一個classes.dex文件,結(jié)構(gòu)如下:

如上的步驟都在Android提供的Gradle套件中,幫我們完成了,Gradle插件依賴的本質(zhì),就是插件文件的下載(Gradle同步)和引用。

到此這篇關(guān)于Android 中的類文件和類加載器詳情的文章就介紹到這了,更多相關(guān)Android 類文件 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android Glide圖片加載(加載監(jiān)聽、加載動畫)

    Android Glide圖片加載(加載監(jiān)聽、加載動畫)

    這篇文章主要為大家詳細(xì)介紹了Android Glide圖片加載的具體實現(xiàn)方法,包括加載監(jiān)聽、加載動畫,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Flutter listview如何實現(xiàn)下拉刷新上拉加載更多功能

    Flutter listview如何實現(xiàn)下拉刷新上拉加載更多功能

    這篇文章主要給大家介紹了關(guān)于Flutter listview如何實現(xiàn)下拉刷新上拉加載更多功能的相關(guān)資料,對于新聞列表數(shù)據(jù)的更新和加載更多是必不可少的,而實現(xiàn)下拉刷新與上劃加載更多的方式有很多種,需要的朋友可以參考下
    2021-08-08
  • Flutter StaggeredGridView實現(xiàn)瀑布流效果

    Flutter StaggeredGridView實現(xiàn)瀑布流效果

    這篇文章主要為大家詳細(xì)介紹了Flutter StaggeredGridView實現(xiàn)瀑布流效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Android中的導(dǎo)航navigation的使用詳細(xì)步驟

    Android中的導(dǎo)航navigation的使用詳細(xì)步驟

    在Android中,導(dǎo)航主要通過使用Navigation SDK來實現(xiàn),該SDK提供了一組工具和組件,可以幫助開發(fā)人員構(gòu)建具有一致性和可訪問性的用戶界面,這篇文章主要介紹了Android中的導(dǎo)航navigation的使用詳細(xì)步驟,需要的朋友可以參考下
    2024-04-04
  • Android中實現(xiàn)自動生成布局View的初始化代碼方法

    Android中實現(xiàn)自動生成布局View的初始化代碼方法

    這篇文章主要介紹了Android中實現(xiàn)自動生成布局View的初始化代碼方法,本文使用解析layout 布局文件的方法實現(xiàn)需求,需要的朋友可以參考下
    2014-10-10
  • Android自定義ViewGroup橫向布局(1)

    Android自定義ViewGroup橫向布局(1)

    這篇文章主要介紹了Android自定義ViewGroup橫向布局,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • Android中Fragment的加載方式與數(shù)據(jù)通信詳解

    Android中Fragment的加載方式與數(shù)據(jù)通信詳解

    本文主要介紹了Android中Fragment的加載方式與數(shù)據(jù)通信的相關(guān)知識。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03
  • 解決Android軟鍵盤彈出覆蓋h5頁面輸入框問題

    解決Android軟鍵盤彈出覆蓋h5頁面輸入框問題

    之前我們在使用vue進(jìn)行 h5 表單錄入的過程中,遇到了Android軟鍵盤彈出,覆蓋 h5頁面 輸入框 問題,在此進(jìn)行回顧并分享給大家,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2018-05-05
  • android使用mysql的方法總結(jié)

    android使用mysql的方法總結(jié)

    在本篇文章中小編給大家整理了關(guān)于android使用mysql的具體方法和實例代碼步驟,需要的朋友們學(xué)習(xí)下。
    2019-05-05
  • Android系統(tǒng)添加自己寫的工具

    Android系統(tǒng)添加自己寫的工具

    今天小編就為大家分享一篇關(guān)于Android系統(tǒng)添加自己寫的工具的文章,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10

最新評論

山东省| 滨海县| 巧家县| 方正县| 安仁县| 瑞丽市| 卢龙县| 东港市| 新巴尔虎左旗| 界首市| 江山市| 丰城市| 郴州市| 江城| 保山市| 上思县| 双城市| 鹿泉市| 临洮县| 遂平县| 静安区| 广宗县| 台中市| 屯留县| 四川省| 东海县| 东兰县| 平潭县| 吴堡县| 蒙城县| 志丹县| 铅山县| 宜良县| 龙海市| 广水市| 拜城县| 新安县| 渝中区| 巴楚县| 泽州县| 靖宇县|