日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android 插件框架实现思路及原理

發布時間:2025/3/15 Android 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android 插件框架实现思路及原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

插件框架實現思路及原理

一、技術可行性

a)?apk的安裝處理流程

i.?apkcopy/data/app

ii.?解壓apk中的class.dex,并對其進行優化,獲得odex(即JIT)。最后保存到/data/dalvik_cache

iii.?還有一些權限和包信息,會緩存到/data/system中的packages.listpackages.xml中。


b)?在android上,對apk包的加載邏輯

i.?加載邏輯

?Zygote(孵化器)在成功啟動一Android進程后,會根據packages.list的內容(啟動時會加載到system_process中的pakcagemanager中),把odex文件,加載到dalvik中,完成邏輯的加載;


ii.?資源讀取

資源讀取,主要有兩三個類,分別是ResourceAssertManagerLayoutInflater

當在顯示界面時,就通過這三個類讀取資源。


c)?結論和猜想

i.?apk相對于整個android系統而言,其本身就是一種插件形式體現。根據上面關于邏輯和資源的讀取概述,完全是可以靜默實現的。其次,class.dex并沒有包含Android?SDK的代碼,只是保留對Android?SDK接口的調用。?可以這樣想象,Android?SDK即插件框架,而Android?OS即為整個插件的宿主環境。因此這就可以解釋了,為什么在1.x編譯的代碼,在2.x甚至3.x都可以運行,因為只要插件宿主的接口(Android?SDK)不變,插件運行時所調用的接口都可以被找到。


ii.?為了減少內存占用,ResourceAssertManagerLayoutInflater必然不會把apk中的所有資源都加載進來,而是用時才加載并緩存,而且還有一些的處理機制(如最不常用清除等)。因此這些類當中,必然存在一個指明資源路徑的字段或者結構。


iii.?要保證兼容性,插件框架公開給插件的接口,必須遵守Open-Close(開發-封閉)原則。另外,一些已經廢棄掉接口,同樣需要保留。比如Service中的setForegroundJDK的中關于Thread的一些接口等。


iv.?可以嘗試通過反射,修改ResourceAssertManagerLayoutInflater中指明資源路徑的字段;另外,還可以查看源碼,查找設置資源路徑的方法。



二、技術實現要點

a)?邏輯加載

i.?針對接口編程。這個是所有插件框架的基本設計模型。

ii.?通過DexClassLoader加載插件所實現的插件接口,詳細可參考PluginManagerImpl中的parserPlugin方法實現,關鍵代碼如下:




b)?AssertManager的實現

經查閱Android源碼,發現AssertManager的實例生成,用到兩個隱藏的方法,如下所示:






通過以上代碼,我們就可以得到我們插件的AssertManager了,關鍵代碼如下所示:




c)?Resource的實現

有了插件專用的AssertManager,那么插件的Resource也輕易得到了,關鍵代碼如下所示:



d)?LayoutInflater的實現

一般我們要獲取LayoutInflater,都必須通過Context來獲得,即是說LayoutInflater的資源讀取,都是通過ContextgetResoure以及getAssert讀取,是直接跟宿主掛勾的。這里有兩個方法可選選擇:

其一,自己重寫Context類,并把getResouregetAssert的返回值改為上面所得的插件資源相關的實例,即包裝法;

其二,考慮到平時我們用LayoutInflater時,主要是用來加載布局文件(XML),因此可以投機取巧點,只針對inflater進行修改。

目前框架采用的是第二種方法。先看看LayoutInflater的源碼實現,如下所示:





因此,只調用插件的Resources,并調用其第二個方法,并可實現加載插件的布局問題,為了方便使用,定義了一個ILayoutInflater接口,封裝實現細節,關鍵代碼如下:




事實上,通過以上的方法,還是無法完成插件XML布局文件的加載,通過跟蹤源碼,會發生View的生成,還需要因為利用到當前Context(Activity)的一個類型Theme的實例。跟蹤過程如下:

l?View(Context?context,?AttributeSet?arrts,?int?defStyle)

l?Context.obtainStyledAttributes(AttrobiteSet?arrts,?int[]??attrs,?int?defStyleAttr,?int?defStyleRes)

l?Context.getTheme()

l?......

而這個Theme類型,是Resource的一個內部類,不單可以直接引用Resource的,還通過Context保存AssertManager的引用。源碼如下:




因此,我們還需要通過反射的方式,把當前Theme的實例,替換成我們插件的。當XML布局文件解釋成功后,再恢復過來。留意上面代碼中的beginend方法,就是這個過程的封裝。關鍵代碼如下:





而插件的Theme實例,可通過ResourcenewTheme獲得,關鍵代碼如下:




e)?混合資源解析的實現

基本上,上面的有了上面的三個類,就可以完全加載插件的讀取插件的資源和邏輯。但往往事情并不是這么簡單。

考慮到UI的可重用性,插件里,往往會很多的用到宿主所提示的UI庫接口。因此,就需要考慮,當在解釋插件的xml布局時,如何混合使用兩方的資源。從上面的過程可得,無論是ResourcesAssertManager還是LayoutInflater,都是同時只能針對一方資源。當在插件的布局文件中,使用了兩方的文件,必然會因為找不到資源,解釋出錯。

不過,LayoutInflater,提示了一個setFactory,可以在解釋XML布局文件時,優先解釋。關鍵代碼如下:







三、待完善的地方

l?在宿主中定義的資源,目前除了自定義view之外,都不可以使用。比如文字、顏色值、樣式等。

l?插件的權限,必須是宿主的子集。

l?插件中包含so的加載邏輯,還沒有實現。

l?目前插件的加載,都是加載dex,而不是odex。還需要查閱源碼,手工實現這個優化過程。



原文地址: http://blog.csdn.net/l173864930/article/details/12235375

總結

以上是生活随笔為你收集整理的Android 插件框架实现思路及原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。