一掷豺、前言
最近騰訊弄出一個(gè)Tinker熱修復(fù)框架,那么本文先不介紹這個(gè)框架吠卷,先來介紹一下阿里的一個(gè)熱修復(fù)框架AndFix,這個(gè)框架出來已經(jīng)很長時(shí)間了沦零,但是看網(wǎng)上沒有太多非常詳細(xì)的講解祭隔,這里就來做一次分析。正好項(xiàng)目中要使用到路操。首先這個(gè)框架是開源的:https://github.com/alibaba/AndFix 其實(shí)在最早的時(shí)候我已經(jīng)分析了阿里的另外一個(gè)熱修復(fù)框架:Dexposed框架疾渴,還不了解的同學(xué)可以點(diǎn)擊這里查看:Dexposed框架原理解析以及使用 當(dāng)時(shí)介紹這個(gè)框架的時(shí)候發(fā)現(xiàn)他的實(shí)現(xiàn)原理很簡單:
他的思想完全來源于Xposed框架,完美詮釋了AOP編程寻拂,這里用到最核心的知識(shí)點(diǎn)就是在native層獲取到指定方法的結(jié)構(gòu)體程奠,然后改變他的nativeFunc字段值,而這個(gè)值就是可以指定這個(gè)方法對應(yīng)的native函數(shù)指針祭钉,所以先從Java層跳到native層瞄沙,改變指定方法的nativeFunc值,然后在改變之后的函數(shù)中調(diào)用Java層的回調(diào)即可慌核。實(shí)現(xiàn)了方法的攔截功能距境。
二、源碼分析
那么本文介紹的AndFix框架相對于Dexposed框架來說又有什么區(qū)別呢垮卓?其實(shí)區(qū)別就在于AndFix框架更加輕便好用垫桂,在進(jìn)行熱修復(fù)的過程中更加方便了。當(dāng)然這個(gè)優(yōu)點(diǎn)在后面的Tinker框架也是能提現(xiàn)出來的粟按。這個(gè)框架的原理是:直接在native層進(jìn)行方法的結(jié)構(gòu)體信息對換诬滩,從而實(shí)現(xiàn)完美的方法新舊替換,從而實(shí)現(xiàn)熱修復(fù)功能灭将。下面通過分析他的源碼來看他的具體實(shí)現(xiàn)疼鸟,下載完源碼之后導(dǎo)入工程:
這里可以看到捂人,因?yàn)樵趎ative層需要替換新舊方法結(jié)構(gòu)體信息卸留,所以這里肯定要做的工作就是虛擬機(jī)的兼容問題,這里做了art和dalvik的分開處理邏輯咳焚,下面來看一下這個(gè)框架的基本使用規(guī)則:
用法還是很簡單的捌朴,這里的修復(fù)包是直接放在本地的吴攒,在實(shí)際操作中會(huì)從網(wǎng)上去下載。下面就開始分析源碼砂蔽,這里有一個(gè)主要的類就是PatchManager:
第一洼怔、PatchManager類初始化
在這個(gè)類的構(gòu)造方法中做了兩件事,一件事是初始化AndFixManager類左驾,一件事是創(chuàng)建修復(fù)包存放的沙盒目錄茴厉。這里先來看第二件事創(chuàng)建沙盒目錄:
可以看到這個(gè)目錄是:/data/data/xxx/files/apatch/xxx.apatch
當(dāng)我們從網(wǎng)上下載好修復(fù)包apatch文件之后泽台,會(huì)調(diào)用addPatch方法,這時(shí)候會(huì)把修復(fù)包復(fù)制到這個(gè)地方矾缓,以后再次啟動(dòng)時(shí)就會(huì)遍歷這個(gè)目錄加載apatch文件。
第二稻爬、AndFixManager的初始化
下面繼續(xù)來看AndFixManager初始化操作:
在這個(gè)初始化中也是干了兩件事:一件事是判斷當(dāng)前環(huán)境是否支持熱修復(fù)嗜闻,一件事是初始化修復(fù)包安全校驗(yàn)的工作,先來看一下判斷是否支持操作:
這里支持的條件是:非YunOS系統(tǒng)桅锄,Android2.3-7.0系統(tǒng)版本琉雳,熱修復(fù)native層設(shè)置是否成功。這里我們看到應(yīng)該值得關(guān)心的是setup操作友瘤,這個(gè)操作其實(shí)是native層進(jìn)行的翠肘,可以直接看一下具體代碼:
這里主要做了一些初始化操作,獲取一些函數(shù)指針辫秧,準(zhǔn)備后續(xù)的replaceMethod函數(shù)中使用:
1束倍、在libdvm.so動(dòng)態(tài)獲取dvmDecodeIndirectRef函數(shù)指針和獲取dvmThreadSelf函數(shù)指針。2盟戏、調(diào)用dest的 Method.getDeclaringClass方法獲取method的類對象clazz绪妹。
繼續(xù)回到AndFixManager的初始化中的第二件事:修復(fù)包安全校驗(yàn)工作,其實(shí)這里只是做了初始化操作柿究,而真正校驗(yàn)的工作在后面邮旷,主要是通過比對應(yīng)用的簽名和修復(fù)包的簽名信息。后面再看吧蝇摸!
第三:PatchManager的初始化操作
這里的初始化做了一件事:是判斷當(dāng)前PatchManager的版本號(hào)是否發(fā)生變化婶肩,如果發(fā)生變化就清空本地所有的修復(fù)包。如果沒有變化貌夕,直接調(diào)用初始化修復(fù)包方法
這個(gè)方法其實(shí)就是我們上面提到的邏輯律歼,會(huì)遍歷沙盒中修復(fù)包目錄中所有的修復(fù)包文件,然后把它添加到修復(fù)列表中蜂嗽。
第四:PatchManager的添加修復(fù)包操作
這里提供了兩個(gè)添加修復(fù)包的方法苗膝,一個(gè)是接受文件樣式的參數(shù):
這個(gè)方法就是上面的那個(gè)initPatchs方法中調(diào)用的地方,這里會(huì)把目錄下所有的修復(fù)包文件加到列表中植旧。這里來看一下另外一個(gè)主要類Patch的初始化操作:
這個(gè)初始化的主要工作就是通過JarFile類解析修復(fù)包文件辱揭,讀取他的META-INF\PATCH.MF文件內(nèi)容,獲取需要修復(fù)類的名稱病附,多個(gè)修復(fù)類之間用逗號(hào)分隔问窃,類似于這樣的樣式:
這里的Utils類就是我們需要修復(fù)的方法所屬的類名,但是這里他又做了處理就是在每個(gè)類的后面加了后綴:_CF完沪。這里分析完了所有需要修復(fù)的類名之后保存到一個(gè)列表中域庇,后面會(huì)通過修復(fù)包名稱獲取到他的修復(fù)類名稱列表嵌戈。
還有一個(gè)添加修復(fù)包文件的方法,接受的是文件路徑參數(shù):
這個(gè)方法接受的是修復(fù)包文件路徑听皿,首先會(huì)把這個(gè)文件拷貝到上面提到的沙盒目錄中以便下次進(jìn)行遍歷操作熟呛,拷貝之后繼續(xù)調(diào)用上面的addPatch方法添加到列表中,最后就在調(diào)用加載修復(fù)包操作了尉姨。
注意:
第一個(gè)方法接受文件樣式的方法其實(shí)是需要結(jié)合上面的initPatchs方法一起使用庵朝,他調(diào)用的場景是:本地沙盒目錄中已經(jīng)有了修復(fù)包文件,并且版本號(hào)沒有發(fā)生變化又厉,這樣每次啟動(dòng)程序的時(shí)候就會(huì)調(diào)用初始化操作九府,在這里會(huì)遍歷沙盒目錄中所有的修復(fù)包文件,然后調(diào)用這個(gè)方法添加到全局文件列表中覆致。
第二個(gè)方法接受的是文件路徑樣式侄旬,這個(gè)方法使用的場景是版本號(hào)發(fā)生變化,或者是本地沙盒中沒有修復(fù)包文件煌妈。比如第一次操作的時(shí)候儡羔,會(huì)從網(wǎng)絡(luò)上下載修復(fù)包文件,下載成功之后會(huì)把這個(gè)文件路徑通過這個(gè)方法調(diào)用即可声旺,執(zhí)行完之后也會(huì)主動(dòng)調(diào)用加載修復(fù)包的操作了笔链,比如這里第一次在SD卡中放了一個(gè)修復(fù)包文件:
只要調(diào)用了這段代碼之后就可以走完了所有的流程了:拷貝修復(fù)包到沙盒目錄中,加載修復(fù)包文件腮猖。
第五:PatchManager的加載修復(fù)包操作
這個(gè)方法有兩個(gè)地方會(huì)調(diào)用到:一個(gè)是上面提到的那個(gè)接受修復(fù)包路徑的addPatch方法鉴扫,一個(gè)是調(diào)用完接受修復(fù)文件類型的addPatch方法之后手動(dòng)調(diào)用一次,類似于這樣:
這個(gè)方法內(nèi)部主要是通過Patch類獲取修復(fù)包所有的修復(fù)類名稱澈缺,之前已經(jīng)介紹了Patch類的初始化操作坪创,在哪里會(huì)解析修復(fù)包的MF文件信息,獲取到修復(fù)包需要修復(fù)的類名然后保存到列表中姐赡,這里就通過getClasses方法來獲取指定修復(fù)包名稱對應(yīng)的修復(fù)類名稱列表莱预,然后在調(diào)用AndFixManager的fix方法即可,下面再來看一下AndFixManager的fix方法的實(shí)現(xiàn)邏輯:
這個(gè)方法有點(diǎn)長项滑,而且內(nèi)容也比較多依沮,這里主要做了這么幾件事:
第一件事:使用上面初始化完成的校驗(yàn)類進(jìn)行修復(fù)包的校驗(yàn)工作,這里的校驗(yàn)就是比對修復(fù)包的簽名和應(yīng)用的簽名是否一致:
這個(gè)具體實(shí)現(xiàn)邏輯不用介紹了枪狂,大家可以下載源碼自己分析危喉。
第二件事:使用DexFile和自定義類加載器來加載修復(fù)包文件
這個(gè)其實(shí)和使用DexClassLoader加載原理類似,而且DexClassLoader內(nèi)部的加載邏輯也是使用了DexFile來進(jìn)行操作的州疾,而這里為什么要進(jìn)行加載操作呢辜限?因?yàn)槲覀冃枰@取修復(fù)類中需要修復(fù)的方法名稱,而這個(gè)方法名稱是通過修復(fù)方法的注解來獲取到的严蓖,所以咋們得先進(jìn)行類的加載然后獲取到他的方法信息薄嫡,最后通過分析注解獲取方法名氧急,這里用的是反射機(jī)制來進(jìn)行操作的。
這個(gè)加載完類之后就會(huì)繼續(xù)調(diào)用fixClass方法毫深,再來看一下fixClass方法實(shí)現(xiàn):
這里主要是通過反射獲取指定類名需要修復(fù)類中的所有方法類型吩坝,然后在獲取到他的注解信息,上面已經(jīng)分析了通過DexFile加載修復(fù)包文件哑蔫,然后在加載上面Patch類中的getClasses方法獲取到的修復(fù)類名稱列表來進(jìn)行類的加載钾恢,然后在用反射機(jī)制獲取類中所有的方法對應(yīng)的注解信息,通過注解信息獲取指定修復(fù)的方法名稱鸳址,看一下這個(gè)注解的定義:
這里提供了兩個(gè)方法,一個(gè)是獲取當(dāng)前類名稱泉懦,一個(gè)是獲取當(dāng)前方法名稱稿黍,可以看一下具體事例:
上面解析完注解信息之后獲取到了方法名稱,緊接著就調(diào)用了replaceMethod方法開始了方法的替換操作
這里還會(huì)做一件事就是通過上面得到的修復(fù)新的方法信息以及需要修復(fù)的舊方法名稱來操作崩哩,不過這里得先獲取到舊方法類型巡球,可以看到修復(fù)的新舊方法的簽名必須一致,所謂簽名就是方法的名稱邓嘹,參數(shù)個(gè)數(shù)酣栈,參數(shù)類型都必須一致,不然這里就報(bào)錯(cuò)的汹押。進(jìn)而也修復(fù)不了了矿筝。最后在調(diào)用了AndFix的addReplaceMethod方法進(jìn)行native層的修復(fù)工作:
這里會(huì)做虛擬機(jī)的區(qū)分處理,但是他們大致的處理邏輯都是一致的棚贾,這里來看一下dalvik的處理機(jī)制:
這里的操作也是非常簡單的窖维,主要是通過上層傳遞過來的新舊方法類型對象,通過JNIEnv的FromReflectedMethod方法獲取對應(yīng)的方法結(jié)構(gòu)體信息妙痹,然后將其信息進(jìn)行替換即可铸史,這里可以看到替換的信息也是非常多的,而且也看到了我們之前介紹Dexposed框架用到的一個(gè)字段值nativeFunc怯伊,這個(gè)就是指定這個(gè)Java方法對應(yīng)的native方法琳轿。但是在這之前也會(huì)看到有一段代碼是用來獲取修復(fù)方法的類信息的,這里主要是用來做修復(fù)方法的類初始化操作耿芹,在之前我們看setup方法的時(shí)候知道崭篡,那里做了這么兩件事:
1、在libdvm.so動(dòng)態(tài)獲取dvmDecodeIndirectRef函數(shù)指針和獲取dvmThreadSelf函數(shù)指針猩系。2媚送、調(diào)用dest的 Method.getDeclaringClass方法獲取method的類對象clazz。
然后在這里就開始獲取修復(fù)方法對應(yīng)的類信息寇甸,通過調(diào)用方法的getDeclaringClass獲取方法對應(yīng)的類對象clazz塘偎,然后在調(diào)用dvm方法獲取到對應(yīng)的類結(jié)構(gòu)體信息ClassObject疗涉,最后在設(shè)置他的狀態(tài)信息標(biāo)記這個(gè)類已經(jīng)初始化完畢了。
注意:
這里可以看到通過一個(gè)類對象clazz類型可以獲取到對應(yīng)的結(jié)構(gòu)體信息ClassObject吟秩,這個(gè)操作也是非常實(shí)用的咱扣,因?yàn)檫@個(gè)結(jié)構(gòu)信息中有一個(gè)字段pDvmDex值,而這個(gè)值就是DvmDex結(jié)構(gòu)體信息也就是底層對應(yīng)的dex文件信息涵防,所以說我們可以通過一個(gè)類信息得到他對應(yīng)的dex文件信息闹伪。
三、流程總結(jié)
到這里就講解完了整個(gè)框架的所有技術(shù)點(diǎn)了壮池,上面可能說的有點(diǎn)亂偏瓤,下面在來大體總結(jié)一下,首先來看一張簡單的流程圖信息(圖片有點(diǎn)大椰憋,可以下載看高清大圖):
第一厅克、Patch類負(fù)責(zé)解析每個(gè)修復(fù)包apatch文件信息,獲取所有需要修復(fù)的類名
這個(gè)類的初始化操作中會(huì)通過傳遞進(jìn)來的修復(fù)包文件橙依,使用JarFile類進(jìn)行文件解析证舟,讀取他的META-INF\PATCH.MF文件信息,主要通過讀取Patch-Classes字段值來獲取需要修復(fù)的類名稱窗骑,多個(gè)類名稱之間用逗號(hào)分隔女责,而且每個(gè)類名稱都有一個(gè)后綴:_CF。解析完成之后就會(huì)保存到一個(gè)用修復(fù)包名稱作為key的HashMap中创译,后面會(huì)通過修復(fù)包名稱參數(shù)來調(diào)用getClasses方法獲取對應(yīng)修復(fù)的類名稱列表抵知。
第二、PatchManager負(fù)責(zé)管理多個(gè)Patch類也就是多個(gè)修復(fù)包信息
主要方法包括初始化昔榴,添加修復(fù)包辛藻,加載修復(fù)包,這個(gè)類是提供給外界調(diào)用的一個(gè)入口類互订,這里有兩種方式調(diào)用:
一種方式是先調(diào)用init方法進(jìn)行初始化吱肌,在這個(gè)初始化方法中會(huì)判斷當(dāng)前的版本號(hào),如果版本號(hào)發(fā)生變化就會(huì)清空本地所有的修復(fù)包文件仰禽,如果沒有變化就加在所有的本地修復(fù)包文件氮墨,而這個(gè)本地目錄就是沙盒中存放修復(fù)包文件的目錄:/data/data/xxx/apatch/xxx.apatch,然后在調(diào)用loadPatch方法進(jìn)行修復(fù)包的加載工作吐葵。
一種方式是本地沒有修復(fù)包文件规揪,也就是第一次操作的時(shí)候可能需要從服務(wù)器下載修復(fù)包文件,這時(shí)候會(huì)把下載下來的修復(fù)包文件路徑通過調(diào)用addPatch方法進(jìn)行添加操作温峭,而這里的添加操作包括了:先把修復(fù)文件拷貝到上面的沙盒修復(fù)包目錄中猛铅,然后在調(diào)用loadPatch方法進(jìn)行加載工作。
第三凤藏、AndFix類主要是和native層交互直接替換方法
這個(gè)類主要就是幾個(gè)native方法用來和底層進(jìn)行交互的操作奸忽,而這些方法都是會(huì)被AndFixManager進(jìn)行調(diào)用的堕伪。
第四、AndFixManager類主要是負(fù)責(zé)管理AndFix類
主要方法包括加載每個(gè)修復(fù)包中需要修復(fù)的類栗菜,解析出每個(gè)類的注解信息獲取該類需要修復(fù)的方法名稱欠雌,初始化的時(shí)候會(huì)進(jìn)行修復(fù)包的校驗(yàn)工作,主要通過對比修復(fù)包和應(yīng)用的簽名信息疙筹。所以可以知道每個(gè)修復(fù)包是需要進(jìn)行簽名操作的富俄,然后他的fix方法會(huì)使用DexFile類進(jìn)行加載修復(fù)包文件,調(diào)用Patch的getClasses方法獲取到所有需要修復(fù)的類名稱進(jìn)行加載操作而咆。然后在調(diào)用fixClass方法霍比,在這個(gè)方法中主要通過遍歷修復(fù)類中所有指定MethodReplace注解信息的方法信息,然后在調(diào)用replaceMethod方法進(jìn)行替換操作暴备,而在這個(gè)方法中也會(huì)通過新方法的Method類型和注解信息中需要修復(fù)方法的名稱來得到舊方法的Method類型桂塞,最終調(diào)用AndFix的native方法replaceMethod進(jìn)行替換操作,所以這里可以看到替換的新舊方法的簽名信息必須一致馍驯,不然無效,也就是方法的名稱玛痊,參數(shù)個(gè)數(shù)汰瘫,參數(shù)類型必須保持一致才可以。
第五擂煞、Native層方法
在native層中會(huì)做art和dalvik虛擬機(jī)的區(qū)分處理工作混弥,他們大致的邏輯都是一致的:
dalvik 模式下的Java hook1、在libdvm.so動(dòng)態(tài)獲取dvmDecodeIndirectRef函數(shù)指針和獲取dvmThreadSelf函數(shù)指針对省。2蝗拿、調(diào)用dest的 Method.getDeclaringClass方法獲取method的類對象clazz。3蒿涎、調(diào)用dvmDecodeIndirectRef方法哀托,獲取clazz的ClassObject4、通關(guān) env->FromReflectedMethod方法獲取dest的Method結(jié)構(gòu)體函數(shù)的指針5劳秋、替換method結(jié)構(gòu)體的成員數(shù)據(jù)art模式下的java hook1仓手、art模式中,我們直接通過 env->FromReflectedMethod獲取到ArtMethod函數(shù)指針玻淑。2嗽冒、然后直接替換ArtMethod結(jié)構(gòu)體的成員數(shù)據(jù)指針
******四、框架使用案例*
上面介紹完了原理补履,下面如果不用案例來做分析添坊,那都是白扯淡,這里我們就用一個(gè)簡單的案例來進(jìn)行實(shí)際操作一下箫锤,而且在這個(gè)過程中會(huì)發(fā)現(xiàn)一個(gè)神奇的工具apatch贬蛙,這里的例子很簡單雨女,本地定義一個(gè)獲取版本號(hào)的方法:
這時(shí)候我們得到這個(gè)值,然后顯示在界面上速客,然后開始出release包戚篙,這里直接用eclipse構(gòu)造簽名文件(這個(gè)簽名文件要記得保存好,后面會(huì)使用到)出包了溺职。等包上線發(fā)布之后岔擂,突然發(fā)現(xiàn)這個(gè)版本號(hào)錯(cuò)了,應(yīng)該是1.0.2浪耘,那么這時(shí)候就需要進(jìn)行熱修復(fù)了乱灵,操作很簡單:
第一步:修改這個(gè)方法返回值為1.0.2
第二步:繼續(xù)使用上面的簽名文件進(jìn)行簽名得到了一個(gè)修復(fù)之后的apk包
第三步:使用神器apatch進(jìn)行線上發(fā)布的release包和這次修復(fù)的fix包進(jìn)行比對,獲取到修復(fù)文件apatch
java -jar apkpatch.jar -f app-release-fix.apk -t app-release-online.apk -o C:\Users\jiangwei1-g\Desktop\apkpatch-1.0.3 -k jiangwei.keystore -p 123456 -a jiangwei -e 123456
這里在使用命令的時(shí)候需要用到簽名文件七冲,因?yàn)樵谇懊娣治龃a的時(shí)候知道會(huì)做修復(fù)包的簽名驗(yàn)證痛倚。這里得到了一個(gè)修復(fù)包文件如下:
而且會(huì)產(chǎn)生一個(gè)diff.dex文件和smali文件夾,這個(gè)就是修復(fù)類的文件對應(yīng)的dex文件和smali代碼:
而我們用壓縮軟件可以打開apatch文件看看:
可以看到這里的classes.dex文件其實(shí)就是上面的diff.dex文件澜躺,只是這里更像是Android中的apk文件目錄格式蝉稳,同樣有一個(gè)META-INF目錄,這里存放了簽名文件以及需要修復(fù)類信息的PATCH.MF文件:
簽名文件就不多說了掘鄙,來看一下PATCH_MF文件信息:
Patch_Classes字段包含了需要修復(fù)的類的名稱信息了耘戚。
第四步:這里為了演示方便,直接把上面的修復(fù)文件拷貝到sd卡中操漠,然后調(diào)用PatchManager的addPatch方法:
第五步:運(yùn)行程序
這時(shí)候可以發(fā)現(xiàn)版本號(hào)已經(jīng)修復(fù)成了1.0.2了收津。
五、apatch工具原理解析
上面看到案例使用比較簡單浊伙,但是看到有一個(gè)比較牛逼的工具就是apatch撞秋,可以生成有方法變動(dòng)的類所在的dex文件,那下面就來一起看看他的實(shí)現(xiàn)原理嚣鄙,沒找到源碼吻贿,直接使用jd-gui查看apatch.jar文件了:
這里的核心代碼就是這部分,會(huì)把有方法變動(dòng)的類信息列表對象DexBackedClassDef借助baksmali類寫入到smali文件中哑子,然后在借助DexBuilder和SmaliMod類把smali類變成dex文件廓八,也就是最終的diff.dex文件了。那么下面在來看一下這個(gè)變動(dòng)的DexBackedClassDef類列表信息如何得到的:
在這里使用DexBackedDexFile類進(jìn)行加載新舊的dex文件赵抢,然后開始比對具體方法實(shí)現(xiàn)變動(dòng)情況剧蹂,主要是方法:compareMethod的實(shí)現(xiàn):
這里會(huì)調(diào)用方法的getImplementation方法來判斷新舊方法的實(shí)現(xiàn)發(fā)生變動(dòng)了,如果有就把當(dāng)前的類對象加入變動(dòng)列表中即可烦却。
所以從這里可以看到這里其實(shí)是完全借助了第三方的功能:可以把dex變成smali文件的baksmali工具包宠叼、可以把smali變成dex文件的smali工具包。而這兩個(gè)工具包的源碼之前在介紹apktool反編譯工具的時(shí)候說到了,想查看源碼的同學(xué)可以查看這篇文章:反編譯利器apktool的源碼解析冒冬。從這里可以看到伸蚯,我們后續(xù)再處理dex,smali等文件格式的時(shí)候這兩個(gè)工具包用的非常多简烤。
六剂邮、框架技術(shù)總結(jié)
到此此次修復(fù)操作就完成了。我們的講解工作和案例演示工作也完成了横侦,下面來總結(jié)一下這個(gè)框架的知識(shí)點(diǎn)挥萌,不過先來看一張大圖(可以點(diǎn)擊下載查看高清大圖):
第一、核心技術(shù)點(diǎn)
從上面可以看到AndFix框架的技術(shù)點(diǎn)主要包括:
1枉侧、使用apatch工具生成修復(fù)包文件引瀑,主要借助baksmali和smali工具包實(shí)現(xiàn)
2、Java層傳遞新舊方法類型對象榨馁,到native層獲取其對應(yīng)的結(jié)構(gòu)體信息實(shí)現(xiàn)完美替換新舊方法結(jié)構(gòu)信息
第二憨栽、優(yōu)點(diǎn)和局限性
優(yōu)點(diǎn):從上面可以看到這個(gè)框架的優(yōu)點(diǎn)在于輕巧便捷,集成成本低翼虫,維護(hù)性強(qiáng)屑柔。
局限性:從上面的代碼分析可以看到這個(gè)框架的局限性還是很多的,特別是他只能修復(fù)對應(yīng)已經(jīng)存在的方法珍剑,比如現(xiàn)在我想增加一個(gè)方法肯定不行的锯蛀,如果想給修復(fù)方法增加參數(shù)信息也是不可以的,這個(gè)局限性就非常大了次慢。還有一個(gè)局限性就是只能進(jìn)行代碼修復(fù),資源是無法做到的翔曲。所以從這里可以看到這個(gè)框架更偏重于方法的熱修復(fù)操作迫像。
項(xiàng)目下載地址:http://download.csdn.net/detail/jiangwei0910410003/9678441
工具下載地址:http://download.csdn.net/detail/jiangwei0910410003/9678885
七、總結(jié)
在開發(fā)過程中現(xiàn)階段熱修復(fù)技術(shù)還是很火的瞳遍,而一些大公司也相繼給出了一些熱修復(fù)的合理方案闻妓,每家都有各自的優(yōu)點(diǎn)和缺點(diǎn),而我就要做到每家熱修復(fù)框架的詳細(xì)原理解析掠械,從中能夠?qū)W習(xí)到更多的技巧和知識(shí)由缆,頂著頭疼的風(fēng)險(xiǎn)寫完了這篇文章,記得多點(diǎn)贊多分享猾蒂!
更多內(nèi)容:點(diǎn)擊這里
關(guān)注微信公眾號(hào)均唉,最新技術(shù)干貨實(shí)時(shí)推送
******掃一掃加小編微信****添加時(shí)注明:“編碼美麗”否則不予通過!**