本發(fā)明涉及dex文件轉(zhuǎn)換技術(shù)領(lǐng)域,具體說是一種可自定義的dex分包的方法。
背景技術(shù):
在android系統(tǒng)中,開發(fā)app的工作隨著業(yè)務(wù)規(guī)模發(fā)展,不斷的加入新的代碼,添加新的類庫,當(dāng)工程中的方法數(shù)超過65535時(shí),就會(huì)遇到以下這個(gè)錯(cuò)誤INSTALL FAILED DEXOPT,導(dǎo)致app無法安裝,開發(fā)無法進(jìn)行。
出現(xiàn)上述問題的原因是:因?yàn)锳ndroid系統(tǒng)使用Dalvik虛擬機(jī),所以需要把使用Java Compiler編譯之后的class文件轉(zhuǎn)換成Dalvik能夠執(zhí)行的dex文件。當(dāng)Android系統(tǒng)啟動(dòng)一個(gè)應(yīng)用(app)的時(shí)候DexOpt(系統(tǒng)內(nèi)部的一個(gè)工具,用來優(yōu)化dex文件,及查看源文件的詳細(xì)信息)會(huì)對(duì)dex文件進(jìn)行優(yōu)化。DexOpt會(huì)把每一個(gè)類的方法id檢索起來,存在一個(gè)鏈表結(jié)構(gòu)里面,但是這個(gè)鏈表的長度是用一個(gè)short類型來保存的,導(dǎo)致了方法id的數(shù)目不能夠超過65535個(gè)。
Dexopt使用一個(gè)固定大小的緩沖區(qū)LinearAlloc來存儲(chǔ)應(yīng)用的方法信息。Android 2.2和2.3的LinearAlloc只有5MB,Android 4.x提高到了8MB或16MB。當(dāng)方法數(shù)量過多會(huì)導(dǎo)致超出緩沖區(qū)LinearAlloc大小,這也會(huì)造成Dexopt崩潰。
現(xiàn)有技術(shù)對(duì)此的解決方案通常是:使用谷歌官方的Multidex Support Library來解決這個(gè)問題,實(shí)現(xiàn)原理是將class編譯進(jìn)不同的classes.dex文件中。這種方法存在以下技術(shù)缺陷:
不能根據(jù)項(xiàng)目實(shí)際需求自動(dòng)智能的指定哪些類必須包含在主dex中,需要人工分析,手動(dòng)指定哪些類應(yīng)該放在主dex中,在大的工程開發(fā)中,人工分析、手動(dòng)添加文件列表的方式顯然不現(xiàn)實(shí),很容易導(dǎo)致應(yīng)用啟動(dòng)時(shí)某些類找不到,出現(xiàn)Class Not Found Exception,造成應(yīng)用崩潰無法使用。
技術(shù)實(shí)現(xiàn)要素:
針對(duì)現(xiàn)有技術(shù)中存在的缺陷,本發(fā)明的目的在于提供一種可自定義的dex分包的方法,在生成dex文件的過程中,對(duì)類文件進(jìn)行依賴分析,動(dòng)態(tài)的指定主dex文件,避免應(yīng)用安裝時(shí)出現(xiàn)錯(cuò)誤INSTALL FAILED DEXOPT,避免運(yùn)行時(shí)出現(xiàn)Class Not Found Exception造成應(yīng)用崩潰無法使用。
為達(dá)到以上目的,本發(fā)明采取的技術(shù)方案是:
一種可自定義的dex分包的方法,其特征在于,包括如下步驟:
步驟101,根據(jù)app首次啟動(dòng)加載所必需類,配置規(guī)則文件,所述規(guī)則文件包括自定義配置的main_dex保留類規(guī)則文件;
步驟102,在編譯過程中,當(dāng)執(zhí)行到dex前置任務(wù)時(shí),根據(jù)步驟101所述規(guī)則文件尋找自定義配置的main_dex保留類的依賴關(guān)系,將找到的自定義配置的main_dex保留類的所有依賴類的全路徑名稱輸出到指定文件;
步驟103,將步驟102所述指定文件中記載的依賴類的全路徑名稱列表,和系統(tǒng)在構(gòu)建時(shí)生成的默認(rèn)的main_dex保留類文件列表合并。
在上述技術(shù)方案的基礎(chǔ)上,步驟101中,所述app首次啟動(dòng)加載所必需類尤指啟動(dòng)頁及程序初始化相關(guān)所必需類。
在上述技術(shù)方案的基礎(chǔ)上,步驟101中,所述規(guī)則文件記載希望保留在main_dex中的類;
規(guī)則具體格式如下:
保留單個(gè)類,以class:開頭,類文件的全路徑名稱為一行;
保留整個(gè)類庫,以jar:開頭,以類庫的全路徑名稱為一行;
以*代表通配符。
在上述技術(shù)方案的基礎(chǔ)上,步驟102的具體步驟如下:
步驟201,在Android Gradle腳本的編譯過程中,在生成main_dex任務(wù)隊(duì)列中插入自定義Task任務(wù);
步驟202,在自定義Task任務(wù)中,調(diào)用分析工具對(duì)步驟101中所述自定義配置的main_dex保留類以及該保留類所依賴的類進(jìn)行循環(huán)分析。
在上述技術(shù)方案的基礎(chǔ)上,步驟201中,任務(wù)隊(duì)列指在Android Gradle腳本編譯構(gòu)建應(yīng)用時(shí),生成main_dex的文件列表,需要經(jīng)歷的Task任務(wù)隊(duì)列。
在上述技術(shù)方案的基礎(chǔ)上,在自定義Task任務(wù)中,調(diào)用Class Dependency Analyzer分析工具,動(dòng)態(tài)的干預(yù)main_dex的文件列表的生成。
在上述技術(shù)方案的基礎(chǔ)上,步驟202的具體步驟如下:
步驟301,讀取步驟101中的規(guī)則文件,將該規(guī)則文件中所有保留類文件名稱列表存在內(nèi)存中;
步驟302,讀取系統(tǒng)混淆后生成的mapping文件,根據(jù)mapping文件中混淆后和混淆前的對(duì)應(yīng)關(guān)系,查找步驟301中所有保留類文件名稱列表對(duì)應(yīng)的混淆之后的類名字,所述混淆之后的類名字為混淆后的類文件名;
步驟303,調(diào)用Class Dependency Analyzer分析工具,以步驟302讀取出來的混淆后的類文件名為索引,通過類文件字節(jié)碼的constant pool,找出類的依賴關(guān)系,這些依賴包括super class、fields、methods及interfaces中出現(xiàn)的類的依賴,將查找出來的保留類的依賴類輸出到臨時(shí)文件中,然后以查找出來的保留類的依賴類為索引,繼續(xù)調(diào)用Class Dependency Analyzer分析工具,直到查找不到類的依賴關(guān)系。
在上述技術(shù)方案的基礎(chǔ)上,在步驟103中,將步驟303所述臨時(shí)文件中記載的所有互相依賴的類的全路徑名稱列表,和系統(tǒng)在構(gòu)建時(shí)生成的默認(rèn)的main_dex保留類文件列表合并,完成干預(yù)系統(tǒng)生成main_dex保留類文件列表的目的。
本發(fā)明所述的可自定義的dex分包的方法,在打包過程中嵌入,針對(duì)系統(tǒng)的主dex文件列表進(jìn)行依賴分析,將遺漏的同時(shí)程序啟動(dòng)時(shí)所必要的類文件打包到主dex中,不依賴于人為的分析主dex文件依賴,避免了人為因素分析不完整,不正確導(dǎo)致出現(xiàn)Class Not Found Exception,造成應(yīng)用崩潰無法使用,穩(wěn)定性、可靠性好。
本發(fā)明所述的可自定義的dex分包的方法,對(duì)其他所有的安卓項(xiàng)目工程同樣具有非常好的適用性。
附圖說明
本發(fā)明有如下附圖:
圖1本發(fā)明方法流程圖。
圖2分析工具進(jìn)行循環(huán)分析流程圖。
具體實(shí)施方式
以下結(jié)合附圖對(duì)本發(fā)明作進(jìn)一步詳細(xì)說明。
如圖1所示,本發(fā)明所述的可自定義的dex分包的方法,包括如下步驟:
步驟101,根據(jù)app首次啟動(dòng)加載所必需類(尤指啟動(dòng)頁及程序初始化相關(guān)所必需類),配置規(guī)則文件,所述規(guī)則文件包括自定義配置的main_dex保留類規(guī)則文件;
步驟102,在編譯過程中,當(dāng)執(zhí)行到dex前置任務(wù)時(shí),根據(jù)步驟101所述規(guī)則文件尋找自定義配置的main_dex保留類的依賴關(guān)系,將找到的自定義配置的main_dex保留類的所有依賴類的全路徑名稱輸出到指定文件;
步驟103,將步驟102所述指定文件中記載的依賴類的全路徑名稱列表,和系統(tǒng)在構(gòu)建時(shí)生成的默認(rèn)的main_dex保留類文件列表合并。
在上述技術(shù)方案的基礎(chǔ)上,步驟101中,所述規(guī)則文件記載希望保留在main_dex中的類;
規(guī)則具體格式如下:
保留單個(gè)類,以class:開頭,類文件的全路徑名稱為一行;
保留整個(gè)類庫,以jar:開頭,以類庫的全路徑名稱為一行;
以*代表通配符。
在上述技術(shù)方案的基礎(chǔ)上,步驟102的具體步驟如下:
步驟201,在Android Gradle腳本的編譯過程(指編譯構(gòu)建應(yīng)用)中,在生成main_dex任務(wù)隊(duì)列中插入自定義Task任務(wù);
步驟202,在自定義Task任務(wù)中,調(diào)用分析工具對(duì)步驟101中所述自定義配置的main_dex保留類以及該保留類所依賴的類進(jìn)行循環(huán)分析。
在上述技術(shù)方案的基礎(chǔ)上,步驟201中,任務(wù)隊(duì)列指在Android Gradle腳本編譯構(gòu)建應(yīng)用時(shí),生成main_dex的文件列表(即默認(rèn)的main_dex保留類文件列表),需要經(jīng)歷的Task任務(wù)隊(duì)列,任務(wù)隊(duì)列具體包括以下Task任務(wù)隊(duì)列:
Task1:collectReleaseMultiDexComponents
該Task1根據(jù)AndroidManifest(指Andriod應(yīng)用程序的清單文件),保留Activity,Service,Broadcastreceiver,ContentProvider,Instrumentation,application,輸出到:
build\intermediates\multi-dex\release\manifest_keep.txt
Task2:PackageAllReleaseClassesForMultiDex
該Task2打包所有的jar,輸出到:build\intermediates\multi-dex\release\allclasses.jar
Task3:ShrinkReleaseMultiDexComponents
該Task3根據(jù)上面的Task 1生成的manifest_keep.txt和Task2生成的allclasses.jar,加上proguard混淆文件,生成混淆后的jar,輸出到:
build\intermediates\multi-dex\release\componentClasses.jar
Task4:createReleaseMainDexClassList
該Task4根據(jù)上面Task 3產(chǎn)生的componentsClasses.jar和Task2產(chǎn)生的allclasses.jar,最終生成main dex list,包含了所有main_dex的class文件,輸出到:
build\intermediates\multi-dex\release\maindexlist.txt
。在Task1~4任務(wù)隊(duì)列中插入自定義Task任務(wù)。
在上述技術(shù)方案的基礎(chǔ)上,在自定義Task任務(wù)中,調(diào)用Class Dependency Analyzer分析工具,動(dòng)態(tài)的干預(yù)main_dex的文件列表的生成。
在上述技術(shù)方案的基礎(chǔ)上,如圖2所示,步驟202的具體步驟如下:
步驟301,讀取步驟101中的規(guī)則文件,將該規(guī)則文件中所有保留類文件名稱列表存在內(nèi)存中;
步驟302,讀取系統(tǒng)混淆后生成的mapping文件,根據(jù)mapping文件中混淆后和混淆前的對(duì)應(yīng)關(guān)系,查找步驟301中所有保留類文件名稱列表對(duì)應(yīng)的混淆之后的類名字,所述混淆之后的類名字為混淆后的類文件名;
所述對(duì)應(yīng)關(guān)系可以通過混淆后生成的類的格式來進(jìn)行精確查找,混淆后的類在類名后面有“:”作為標(biāo)示,以下是一個(gè)示例:
混淆前的類名“android.net.http.SslError”,
混淆后的類名“android.a.a.a:”,
步驟303,調(diào)用Class Dependency Analyzer分析工具,以步驟302讀取出來的混淆后的類文件名為索引,通過類文件字節(jié)碼的constant pool(常量池),找出類的依賴關(guān)系,這些依賴包括super class(類的父類)、fields(類的字段)、methods(類的方法)及interfaces(類的接口)中出現(xiàn)的類的依賴,將查找出來的保留類的依賴類輸出到臨時(shí)文件中,然后以查找出來的保留類的依賴類為索引,繼續(xù)調(diào)用Class Dependency Analyzer分析工具,直到查找不到類的依賴關(guān)系。
在上述技術(shù)方案的基礎(chǔ)上,在步驟103中,將步驟303所述臨時(shí)文件中記載的所有互相依賴的類的全路徑名稱列表,和系統(tǒng)在構(gòu)建時(shí)生成的默認(rèn)的main_dex保留類文件列表合并,完成干預(yù)系統(tǒng)生成main_dex保留類文件列表的目的。
本說明書中未作詳細(xì)描述的內(nèi)容屬于本領(lǐng)域?qū)I(yè)技術(shù)人員公知的現(xiàn)有技術(shù)。