Android插件基礎之類加載器學習

記錄學習java 加載器學習所獲心得,逐步記錄了解java加載器的過程。為了知悉android 插件化的實現原理,從而需要從頭了解android加載apk,以及基礎的java類加載的加載過程情況,為方便記錄和記憶,故此將學習了解的過程記錄成文字,以下文字記錄部分可能來自與多個來源,主體以Java源碼和IBM開發者博客有關java加載技術的博客為主。

Java 類的加載過程

慣性思維,想要了解apk的加載過程,我希望先簡單知道以下Java中對類加載過程的處理(Java一直都是android的官方開發語言,雖然現在kotlin也是,但原理不變)。首先需要了解Java 類在jvm中的加載過程,基本的流程如下:

加載流程

  • 裝載
    裝載是通過已經編譯生成的class文件的位置查找文件獲取其字節流導入class文件,并將其轉換成一個Class類的一個實例,將類的實例存放在jvm的堆區,獲取裝載類的信息到方法區(屬于jvm的內存區域的一種,主要用于存放類的字段、方法,常量池等信息),這里就是負責處理完成類的加載的過程,主要是由ClassLoader及其子類完成。

  • 鏈接
    其主要功能就是對類信息格式進行校驗,分配方法區域的類變量的初始值(并非設置的初始化數值,而是初始“0”值)并將類的引用指向對應類的實例。其內部分為三個過程:校驗 —>準備—>解析。執行順序為既定的。

  • 初始化
    初始化類的靜態變量和靜態代碼塊(相對于鏈接中的準備階段,將已經“初始化”的靜態數據進行真正的初始化).類的初始化情況:
    1)遇到類的創建指令New指令
    2)java主運行程序的入口類的實例
    3)通過反射創建類(newInstance、forClass等)
    4)子類初始化觸發父類的初始化操作
    5)java 1.7動態類型初始化

  • 使用和卸載
    對創建java對象的操作以及java回收機制對jvm的自動回收卸載。

Java 類加載器

如上,對于java類的加載使用,屬于應用層程序員可控過程就只有類的加載過程,通過指定類的加載器來加載我們的類信息,首先通過java的源碼文檔來簡單了解一下類加載的介紹。類加載器位置:

java.lang.ClassLoader.java

文檔介紹為:類加載器主要負責加載類的對象,通過給定一個類的“二進制名稱”,那么類加載器會嘗試定位或身成類定義的數據信息。一般策略是將二進制名稱轉化為一個文件的名稱并加載該類文件的二進制數據。數組類型的類的對象并不是由類加載器創建,而是java 運行時根據需要自動創建.數組類型的加載器由Class.getClassLoader()返回.該加載器與其元素類型的類加載器是相同的;如果該元素類型是基本類型,則該數組類沒有類加載器。

程序可以通過繼承ClassLoader的子類來擴展動態加載方式.類加載器支持雙親委托模型(通過委托父類查找資源的方式進行操作)查找類或類的資源.虛擬機的內置類加載器(稱為 “bootstrap class loader”)本身沒有父類加載器,但是可以將它用作 ClassLoader 實例的父類加載器……

如上,為部分對于ClassLoader的介紹文字.對于通用類加載器通常將其分為四個類型,如下介紹:

  • 引導型類加載器(bootstrap)
    該類加載器并沒有父類類加載器,具體實現是通過原生代碼實現(平臺相關的),用于加載Java的核心代碼,無法直接通過代碼使用.

  • 擴展型類加載器
    它用來加載 Java 的擴展庫。Java 虛擬機的實現會提供一個擴展庫目錄。該類加載器在此目錄里面查找并加載 Java 類。android中相當于java.lang.BootClassLoader

  • 系統類加載器(system class loader)
    它根據 Java 應用的類路徑(CLASSPATH)來加載 Java 類。一般來說,Java 應用的類都是由它來完成加載的。可以通過 ClassLoader.getSystemClassLoader()獲取。android 中相當與dalvik.system.PathClassLoader.

  • 線程上下文類加載器
    用于設置和獲取線程上下文的類加載器,若是未曾設置該加載器,線程上下文類加載器將繼承自父線的上下文類加載器,而Java應用初始線程上下文類加載器為系統加載器,android中也就是繼承自BaseDexClassLoader的子類加器PathClassLoader或者DexClassLoader加載器.

    基于Android 平臺對于以上的加載器做一個簡單的代碼測試如下:


var loader=classLoaderwhile (loader != null) {println("加載器類型:${loader.toString()}")loader = loader.parent}//輸出結果如下10-30 17:55:05.964 23338-23338/com.enjoytoday I/System.out: 加載器類型:dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.enjoytoday-2/base.apk", zip file "/data/app/com.enjoytoday-2/split_lib_dependencies_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_0_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_1_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_2_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_3_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_4_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_5_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_6_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_7_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_8_apk.apk", zip file "/data/app/com.enjoytoday-2/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.enjoytoday-2/lib/arm64, /system/fake-libs64, /data/app/com.enjoytoday-2/base.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_dependencies_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_0_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_1_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_2_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_3_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_4_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_5_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_6_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_7_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_8_apk.apk!/lib/arm64-v8a, /data/app/com.enjoytoday-2/split_lib_slice_9_apk.apk!/lib/arm64-v8a, /system/lib64, /vendor/lib64, /system/vendor/lib64, /product/lib64]]]
10-30 17:55:05.964 23338-23338/com.enjoytoday I/System.out: 加載器類型:java.lang.BootClassLoader@d725e7d

Android 中的類加載器

Android 中的虛擬機是由dalvik來實現,dalvik并非典型的Java虛擬機。因此,其類的加載器和標準有所不同,對于dalvik而言,其并不可以直接識別加載class文件,而是對class打包成的dex文件進行加載。因此,Android源碼對ClassLoader進行處理,并派生一個子類BaseDexClassLoader,其本質類似于jvm中的ClassLoader,確切的說可以說是一個Dex加載器。

基于Android 平臺的類加載器結構如下:

android dex加載結構

  • BootClassLoader
    是屬于ClassLoader的一個內部類,不可直接使用,每個ClassLoader中都存在一個parent(ClassLoader類型),父類加載器,而BootClassLoader屬于最頂層的parent.

  • URLClassLoader
    這個是一個輸入jar的加載器,在java中支持在線或本地指定jar文件來加載jar包,但由于android中dalvik并不可以識別class或者jar,只能加載dex,所以并不可以直接使用URLClassLoader來加載jar文件

  • BaseDexClassLoader

這個屬于加載dex文件的加載器的實現,具體的加載邏輯在其中實現

  • PathClassLoader
    繼承自BaseDexClassLoader,為默認apk安裝使用的類加載器,會自動尋址apk安裝后默認解壓后的dex路徑,目前dalvik并不支持使用PathClassLoader來加載未安裝的apk,但也有文章說art可以實現,暫未驗證,不能確認。

  • DexClassLoader
    繼承自BaseDexClassLoader,可以直接加載dex,壓縮文件(apk文件),jar文件,是實現android插件化一個重要的元素,可以幫我們完成對為安裝的插件apk的加載過程.

android基本加載知識記錄,已留備存。

Enjoytoday,EnjoyCoding

轉載于:https://www.cnblogs.com/amiko/p/7906204.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/287321.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/287321.shtml
英文地址,請注明出處:http://en.pswp.cn/news/287321.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

php多個文件上傳代碼,PHP單文件上傳類或多文件上傳類源碼

以下為引用的內容:php文件:代碼://如果收到表單傳來的參數,則進行上傳處理,否則顯示表單if(isset($_FILES[uploadinput])){//建目錄函數,其中參數$directoryName最后沒有"/",//要是有的話,以/打散…

《看聊天記錄都學不會C語言?太菜了吧》(13)(9*9 乘法表)尋找電腦中的盲盒彩蛋

若是大一學子或者是真心想學習剛入門的小伙伴可以私聊我,若你是真心學習可以送你書籍,指導你學習,給予你目標方向的學習路線,無套路,博客為證。 本系列文章將會以通俗易懂的對話方式進行教學,對話中將涵蓋…

Fragment使用--文章集錦

android使用Fragment實現底部菜單使用show()和hide()來切換以保持Fragment狀態Android Fragment 真正的完全解析(上)Android Fragment實踐(一)糾正對Fragment Transaction BackStack的誤解多個Fragment 切換時不重新實例化Fragment詳解之四——管理Fragm…

Android之在在EditText的xml里面配置了相關屬性依然沒有顯示光標問題

1 問題 在EditText的xml里面配置了 android:cursorVisible"true" android:focusable"true" android:focusableInTouchMode"true" 依然沒有光標顯示 2 解決辦法 直接在代碼層控制,平且拉起鍵盤 fun showSoftInputFromWindow(activ…

【經典回放】多種語言系列數據結構線性表之二:鏈表

目錄 1 鏈表結構設計 2 簡單的鏈表測試 2 鏈表的組織和ADT設計 3 初始化有頭結點鏈表 4 有頭結點鏈表中追加一個結點(一行數據)

使用 Postman 實現 API 自動化測試

1背景介紹 相信大部分開發人員和測試人員對 postman 都十分熟悉,對于開發人員和測試人員而言,使用 postman 來編寫和保存測試用例會是一種比較方便和熟悉的方式。但 postman 本身是一個圖形化軟件,相對較難或較麻煩(如使用 …

php json -gt;訪問,【轉】Php+ajax+jsonp解決ajax跨域問題

首先:jsonp是json用來跨域的一個東西。原理是通過script標簽的跨域特性來繞過同源策略。發送端:$.ajax({type : "post",url : "ajax.php",dataType : "jsonp",jsonp: "callback",//傳遞給請求處理程序或頁面的&…

《看聊天記錄都學不會Python到游戲實戰?太菜了吧》(1)加載Python神器!亮劍!

本系列文章將會以通俗易懂的對話方式進行教學,對話中將涵蓋了新手在學習中的一般問題。此系列將會持續更新,包括別的語言以及實戰都將使用對話的方式進行教學,基礎編程語言教學適用于零基礎小白,之后實戰課程也將會逐步更新。 若…

little tricks(持續更新)【python】

python中的list有reverse方法,但是字符串卻沒有,怎么辦呢? csdn博主有列了幾個方法,我覺得第一個最簡單直接,str[::-1]搞定。 當然也有一種怪異的方法,我把字符串轉為序列reverse一下,再轉回來不…

Codeigniter 3 拓展HMVC

2019獨角獸企業重金招聘Python工程師標準>>> 在Codeiniter(以下統稱CI) 2.X版本中,我們就通過拓展核心類庫實現了HMVC,但是同樣的代碼,拿到CI 3中,就很有可能不好用了。 ###拓展核心類庫方式 官…

FPGA FIFO深度計算

轉自:http://comm.chinaaet.com/adi/blogdetail/37555.html 首先,一定要理解清楚FIFO的應用場景,這個會直接關系到FIFO深度的計算,如果是面試官拋出的問題,那么有不清楚的地方,就應該進行詢問。如果是筆試或…

玩轉ASP.NET Core 6.0框架-序言

ASP.NET Core是微軟提供的強大的web框架,它有很多潛在的強大而有用的功能。本專欄的目標是幫助您把框架的隱藏能力最大限度地發揮出來,讓您能夠按需定制ASP NET Core框架。本專欄提供了一種具體的操作和實現方法,可以讓你在短時間盡可能地提高…

從C#開始的面向對象編程經典自學教程

1、C語言的時代 在C語言時代,可以認為那時的編程過程就是表格加工過程,也就是從A表格到B表格、再到C表格…..等等,這個過程中,計算機語言如何描述一個表格,成為計算機語言的關鍵。 對一個表格的分析可以發現:表格是兩部分組成:表頭和表格: 學生表 STUDENT 在這個表格…

Java之對List里面的對象名字進行模糊查詢

1 問題 對list里面的對象名字進行模糊查詢 2 解決辦法 //即可以進行模糊匹配matcher.find()//匹配查詢matcher.matches() /*** 模糊查詢*/public static ArrayList<SearchBean> search(String name, List<SearchBean> list) {ArrayList<SearchBean> results…

《看聊天記錄都學不會Python到游戲實戰?太菜了吧》(2)在python中加號竟然如此善變

本系列文章將會以通俗易懂的對話方式進行教學&#xff0c;對話中將涵蓋了新手在學習中的一般問題。此系列將會持續更新&#xff0c;包括別的語言以及實戰都將使用對話的方式進行教學&#xff0c;基礎編程語言教學適用于零基礎小白&#xff0c;之后實戰課程也將會逐步更新。 若…

mysql數據庫rp集群,使用MySQL-Cluster搭建MySQL數據庫集群

1、MySQL集群的作用&#xff1a;- 解決訪問節點的單點故障- 數據存儲節點的單點故障- 解決數據存儲節點數據備份問題2、集群&#xff1a;使用一組服務器提供相同的服務3、關于MySQL-Cluster&#xff1a;MySQL官方提供的集群版本已集成標準版MySQL程序&#xff0c;可獨立安裝使用…

桌面虛擬化云技術將支撐數字化醫院

桌面虛擬化云技術將支撐數字化醫院 2013-12-04 10:32 現今醫療行業已經從醫院——患者的二元關系走向從醫院——患者——政府監督——醫療保險的多元關系&#xff0c;醫療體系需要更高效的運轉&#xff0c;患者需要更好的就醫體驗&#xff0c;這使得醫療行業信息化建設的重要性…

Blazor University (23)路由 —— 路由參數

原文鏈接&#xff1a;https://blazor-university.com/routing/route-parameters/路由參數源代碼[1]到目前為止&#xff0c;我們已經了解了如何將靜態 URL 鏈接到 Blazor 組件。靜態 URL 只對靜態內容有用&#xff0c;如果我們希望同一個組件根據 URL 中的信息&#xff08;例如客…

【經典回放】多種語言系列數據結構算法:棧(C版)

本文采用C語言實現棧結構算法并舉例應用。 一 棧的基本原理分析 作為棧這種數據結構,數據是進行所謂的先進后出操作,但棧在操作中,并不需要在中間插入刪除操作、一般也不需要在進棧數據中查找什么,這種情況下,恰恰是順序表可以完成的非常好的場合,所以棧經常是用一個簡單…

Android之提示android.content.res.Resources$NotFoundException: Resource ID #0x7f08010a

1 問題 在我的oppo機器上面運行一個頁面沒有奔潰,但是在紅米安卓5.1版本運行頁面奔潰,奔潰信息如下 /Timeline(11600): Timeline: Activity_launch_request time:61313216 I/WtProcessController( 3721): FOREGROUND INFO: name=com.appsinnova.android.keepshare uid=1023…