在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個必要的...