aapt 如何修改資源ID

2021-07-09 09:37:45 字數 2887 閱讀 8506

在android專案中,出現資源id(packageid+typeid+itemvalue)發生衝突的問題。特別是外掛程式化開發的需求背景時(網上有很多解決方案,不一一枚舉,如public 限定等)。那麼對於我們自己提供的庫包,如果能指定其包的命令空間(預設是從127開始),特別考慮mutidex的情況,自定義修改package id顯得意義重大。網上已經有很多修改package id 的aapt可執行檔案(但是絕大部分不提供原始碼,覺得很神,就決定自己研究一下),通過命令列引數提供package id賦值,現在從aapt資源打包原始碼流程角度,

講解該過程中何時會生成應用程式包的package id, 然後如何進行修改。

aapt首先根據命令列引數路徑,尋找到androidmanifest檔案,提取出應用程式的名稱,建立resourcetable.

具體呼叫路徑

main(main.cpp)-->handlecommand(command.cpp)->dopackage-->buildresources(resource.cpp)

status_t buildresources(bundle* bundle,

const sp

& assets)

status_t err

= parsepackage(bundle, assets, androidmanifestfile);if

(err

!= no_error)

noisy(printf(

"creating resources for package %s\n"

,assets-

>getpackage().

string()

));resourcetable table(bundle, string16(assets-

>getpackage())

);err= table.addincludedresources(bundle, assets);

從第5行到第20行,我們需要關注的過程主要是讀取androidmanifest.xml內的應用名稱(parsepackage比較麻煩,它會收集工程xml檔案的元素《資源》資訊,並對xml進行扁平壓縮,最終寫入到

resxmltree的資料結構中),來建立乙個資源表resourcetable(資源打包最後階段會根據該內容生成資源索引表resources.arsc),在上述**第21行,我們能看到

table

.addincludedresources

(bundle

,assets

);該函式主要是用於新增被引用的資源包,當然一般是系統資源包android.jar.

status_t resourcetable:

:addincludedresources(bundle* bundle,

const sp

& assets)//

for future reference to included resources.

massets = assets;

const restable& incl = assets-

>getincludedresources();

// retrieve all the packages.

const size_t n = incl.getbasepackagecount();

for(size_t phase=0; phase<2; phase++)

else

}else

if(id !

= 0)

true;}

if(mnextpackageid > id)}if

(id !

= 0)}}

}// every resource table always has one first entry, the bag attributes.

const sourcepos unknown(string8(

"????"

), 0)

;sp attr = gettype(massetspackage, string16(

"attr"

), unknown)

;return no_error;}

從上述**14行到第55行,描述了新增引用依賴包的過程,核心在第46-48行,以pair的格式存入依賴包(注意id為包命名空間8位二進位制,系統層為1)。

從第59行gettype()開始就要進入到當前資源包id的命名了,

resourcetable

::gettype()---》call resourcetable::getpackages()

sp:package> resourcetable:

:getpackage(

const string16& package)

else

iftrue

;p = new package(package, 127);}

else

//printf(

"*** new package: \"

%s\" id=%d\n",/

/ string8(package)

.string()

, p-

>getassignedid())

;mpackages.add(package, p)

;morderedpackages.add(p)

;mnextpackageid++;

}return p;}

在這裡我們應用程式的id賦值在第14行,最終在第20行到21行完成對新包的加入,**相對比較簡單,不再進行贅述,至此,應用程式的包id被賦值為0x7f(127).

那麼到了這裡大家大概知道如何修改原始碼了,是不是只要把127換成乙個其它數字就可以了呢,可以說確實是的。我們只需要對bundle資料結構進行擴充套件,將id-127換成從bundle讀入的乙個變數即可。

使用aapt2 修改apk打包的資源id

在進行外掛程式化開發時,如果外掛程式apk含有res資源,宿主apk和外掛程式apk在編譯時都會產生自己的resources.arsc。由於打包後的宿主和外掛程式apk資源id預設都是0x7f開頭,那麼它們的resources.arsc中的資源id必定是有相同的情況,會引起資源id衝突問題。解決問題...

android 資源ID規則

在使用listactivity的時候會遇到使用android預設id名稱的時候,例如 android id list 我們在新建乙個資源的時候,我們需要給這個資源附乙個id,例如 id textname 我們在引用乙個資源的時候,需要提供他的id,例如 style font1 在這裡總結一下id的使...

如何修改id 白卡 面試官 MVCC是如何實現的?

mvcc即多版本併發控制,通過讀取指定版本的歷史記錄,並通過一些手段保證讀取的記錄值符合事務所處的隔離級別,在不加鎖的情況下解決讀寫衝突 如果小夥伴對mvcc不熟,估計看了這句話會有點懵,沒事,等看完這篇文章你就能看懂這句話了 對於使用innodb儲存引擎的表來說,聚集索引記錄中都包含下面2個必要的...