最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Android中實現(xiàn)熱更新的原理

 更新時間:2016年01月12日 09:21:13   作者:大頭鬼Bruce  
這篇文章主要為大家介紹了Android 熱更新實現(xiàn)原理,及代碼分析,感興趣的小伙伴們可以參考一下

這篇文章就來介紹一下Android中實現(xiàn)熱更新的原理。

一、ClassLoader
我們知道Java在運行時加載對應(yīng)的類是通過ClassLoader來實現(xiàn)的,ClassLoader本身是一個抽象來,Android中使用PathClassLoader類作為Android的默認的類加載器,PathClassLoader其實實現(xiàn)的就是簡單的從文件系統(tǒng)中加載類文件。PathClassLoade本身繼承自BaseDexClassLoader,BaseDexClassLoader重寫了findClass方法,該方法是ClassLoader的核心。

@Override

protected Class> findClass(String name) throws ClassNotFoundException {

  List suppressedExceptions = new ArrayList();

  Class c = pathList.findClass(name, suppressedExceptions);

  if (c == null) {

    ClassNotFoundException cnfe = new ClassNotFoundException("Didn't find class /"" + name + "/" on path: " + pathList);

    for (Throwable t : suppressedExceptions) {

      cnfe.addSuppressed(t);

    }

    throw cnfe;

  }

  return c;

}

看源碼可知,BaseDexClassLoader將findClass方法委托給了pathList對象的findClass方法,pathList對象是在BaseDexClassLoader的構(gòu)造函數(shù)中new出來的,它的類型是DexPathList??聪翫exPathList.findClass源碼是如何做的:

public Class findClass(String name, List 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;

}

直接就是遍歷dexElements列表,然后通過調(diào)用element.dexFile對象上的loadClassBinaryName方法來加載類,如果返回值不是null,就表示加載類成功,會將這個Class對象返回。而dexElements對象是在DexPathList類的構(gòu)造函數(shù)中完成初始化的。

this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory, suppressedExceptions);
makeDexElements所做的事情就是遍歷我們傳遞來的dexPath,然后一次加載每個dex文件。

二、實現(xiàn)
上面分析了Android中的類的加載的流程,可以看出來DexPathList對象中的dexElements列表是類加載的一個核心,一個類如果能被成功加載,那么它的dex一定會出現(xiàn)在dexElements所對應(yīng)的dex文件中,并且dexElements中出現(xiàn)的順序也很重要,在dexElements前面出現(xiàn)的dex會被優(yōu)先加載,一旦Class被加載成功,就會立即返回,也就是說,我們的如果想做hotpatch,一定要保證我們的hotpacth dex文件出現(xiàn)在dexElements列表的前面。

要實現(xiàn)熱更新,就需要我們在運行時去更改PathClassLoader.pathList.dexElements,由于這些屬性都是private的,因此需要通過反射來修改。另外,構(gòu)造我們自己的dex文件所對應(yīng)的dexElements數(shù)組的時候,我們也可以采取一個比較取巧的方式,就是通過構(gòu)造一個DexClassLoader對象來加載我們的dex文件,并且調(diào)用一次dexClassLoader.loadClass(dummyClassName);

方法,這樣,dexClassLoader.pathList.dexElements中,就會包含我們的dex,通過把dexClassLoader.pathList.dexElements插入到系統(tǒng)默認的classLoader.pathList.dexElements列表前面,就可以讓系統(tǒng)優(yōu)先加載我們的dex中的類,從而可以實現(xiàn)熱更新了。

下面展示一部分代碼

private static synchronized Boolean injectAboveEqualApiLevel14(

      String dexPath, String defaultDexOptPath, String nativeLibPath, String dummyClassName) {

  Log.i(TAG, "--> injectAboveEqualApiLevel14");

  PathClassLoader pathClassLoader = (PathClassLoader) DexInjector.class.getClassLoader();

  DexClassLoader dexClassLoader = new DexClassLoader(dexPath, defaultDexOptPath, nativeLibPath, pathClassLoader);

  try {

    dexClassLoader.loadClass(dummyClassName);

    Object dexElements = combineArray(

        getDexElements(getPathList(pathClassLoader)),

        getDexElements(getPathList(dexClassLoader)));

    Object pathList = getPathList(pathClassLoader);

    setField(pathList, pathList.getClass(), "dexElements", dexElements);

  } catch (Throwable e) {

    e.printStackTrace();

    return false;

  }

  Log.i(TAG, "

Android中實現(xiàn)熱更新的原理先為大家介紹到這,大家可以結(jié)合平時積累的知識,查閱相關(guān)書籍進行深入學(xué)習(xí)探究,希望大家能夠有所收獲。

相關(guān)文章

最新評論

沭阳县| 淮南市| 松阳县| 鄂托克旗| 贵溪市| 淮安市| 台东市| 娱乐| 赫章县| 呼伦贝尔市| 建阳市| 临江市| 潮安县| 洪雅县| 灵宝市| 寻甸| 营山县| 九龙县| 锡林浩特市| 曲沃县| 保定市| 达拉特旗| 阜康市| 抚顺市| 黑山县| 西乌珠穆沁旗| 张北县| 嘉义市| 乐陵市| 昆明市| 保定市| 阿坝县| 兴山县| 青岛市| 齐齐哈尔市| 章丘市| 杭州市| 丰都县| 松滋市| 广德县| 邯郸市|