Android 熱修復技術(1)---原理


熱修復技術分為幾部分:

原理介紹

Android HotFix源碼分析

自定義框架

1.Android分包MultiDex原理

首先Dex是什么東西?

Dex就是Window里面的exe文件 也就是可執行問題。

Android沒有用傳統的Java虛擬機,而是使用dalvik虛擬機。當APK安裝到手機后,dalvik會先把de文件轉化位ODEX文件,

優化結構。

在早期的android系統中,為了優化dex,所有的method會存放在一張表里面,表的大小位short,也就是65535(65K)

But現在android代碼非常多,超過65K很正常,這個時候就需要一種解決方案來解決這個問題。

簡單來說就是將編譯好的class文件分拆成2個dex文件,繞過65k的限制。

關於分包的具體實現,可以參考dex分包方案概述與multidex包的配置使用

2.Android熱補丁修復技術原理

目的:有時候需要修改幾行代碼,但是我們需要重發各個市場,重新release等。是不是可以只是簡單的打patch就可以解決這個問題呢?

首先來看dex加載的源碼:

public Class findClass(String name, List<Throwable> suppressed) {
    for (Element element : dexElements) {
        DexFile dex = element.dexFile;

        if (dex != null) {
            Class clazz = dex.loadClassBinaryName(name, definingContext, suppressed);
            if (clazz != null) {
                return clazz;
            }
        }
    }
    if (dexElementsSuppressedExceptions != null) {
        suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions));
    }
    return null;
}

每個element對應的就是dex文件,所以加載class就是從一個個dex文件中找到對應的code。but,可以發現,一旦找到成功了以后,就直接return。

也就是說如果2個dex含有相同的class,會先返回前面那個。

so 我們的解決方案來了,使用一個新的dex,讓他在element文件表的最前面,這樣我們修改的class文件就會被首先加載進來。

理論上,如果在不同的dex中有相同的類存在,那么會優先選擇排在前面的dex文件的類,如下圖:


在此基礎上,我們構想了熱補丁的方案,把有問題的類打包到一個dex(patch.dex)中去,然后把這個dex插入到Elements的最前面,如下圖:

好,該方案基於第二個拆分dex的方案,方案實現如果懂拆分dex的原理的話,大家應該很快就會實現該方案,如果沒有拆分dex的項目的話,可以參考一下谷歌的multidex方案實現。然后在插入數組的時候,把補丁包插入到最前面去。

But 我們發現在插入patch.dex后,會報錯,原因是CLASS_ISPREVERIFIED。這是個什么東東?

在類的方法中直接引用的類,如果在同一dex中,就會被打上CLASS_ISPREVERIFIED這個標志。

我們單獨給一個AntilazyLoad類打包成hack.dex 這樣每個class里面都調用。我們在構造函數里面添加:

public class A{
    public A()
    {
        system.println(AntilazyLoad.class);
    }
}

So,這樣A就引用了不在一個dex里面的class,從而不會被打上CLASS_ISPREVERIFIED的代碼。進而不會出現問題。

參考:

安卓App熱補丁動態修復技術介紹

http://my.oschina.net/853294317/blog/308583

http://blog.csdn.net/lmj623565791/article/details/49883661

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM