绝望的DexMaker学习之路(一)——DexMaker类的generateAndLoad函数

目前好像并没有很多关于Dexmaker类的源码解析,所以公开了这篇博客。我的Dexmaker库学习之路在看到生成注解的类的源码时走到了尽头,不过也许会随着源码的完善而继续下去也说不准

一.源码

public ClassLoader generateAndLoad(ClassLoader parent, File dexCache) throws IOException {
        if (dexCache == null) {
            String property = System.getProperty("dexmaker.dexcache");
            if (property != null) {
                dexCache = new File(property);
            } else {
                dexCache = new AppDataDirGuesser().guess();
                if (dexCache == null) {
                    throw new IllegalArgumentException("dexcache == null (and no default could be"
                            + " found; consider setting the 'dexmaker.dexcache' system property)");
                }
            }
        }

        File result = new File(dexCache, generateFileName());
        // Check that the file exists. If it does, return a DexClassLoader and skip all
        // the dex bytecode generation.
        if (result.exists()) {
            return generateClassLoader(result, dexCache, parent);
        }

        byte[] dex = generate();

        /*
         * This implementation currently dumps the dex to the filesystem. It
         * jars the emitted .dex for the benefit of Gingerbread and earlier
         * devices, which can't load .dex files directly.
         *
         * TODO: load the dex from memory where supported.
         */
        result.createNewFile();
        JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(result));
        JarEntry entry = new JarEntry(DexFormat.DEX_IN_JAR_NAME);
        entry.setSize(dex.length);
        jarOut.putNextEntry(entry);
        jarOut.write(dex);
        jarOut.closeEntry();
        jarOut.close();
        return generateClassLoader(result, dexCache, parent);
    }

二.该函数的运行机制

第一次成功运行了demo之后,我更改了demo中变量的值,观察到发现打印出的值没有变化。

下面我们来探究一下为什么会出现这个问题:

通过断点调试,我发现,在生成dex文件之前会先生成一个jar文件(此时这个jar文件是没有后期生成的dex文件的内容的,dex文件的内容是后面写入到这个jar文件中的)

然后判断是否已经存在,如果不是第一次运行这个程序,result.exsits()的结果就会是true,然后执行图中的这个语句,用之前生成的jar文件进行下一步的操作

下面我们来进一步看一下result.exists(),这个函数调用了StrictMode.java中的一个函数

绝望的DexMaker学习之路(一)——DexMaker类的generateAndLoad函数_第1张图片

接下来,该怎样解决这个问题呢?

最初的想法是重写这个函数,但是源码中的DexMaker类被定义成了final的。并且,生成jar文件的文件名的函数也是在DexMaker中定义的,所以我们也不能通过加个随机数的方法每次生成不同的文件名。那么就只剩了一个办法,每次重新生成之前先清除文件夹中之前生成的文件。

你可能感兴趣的:(绝望的DexMaker学习之路(一)——DexMaker类的generateAndLoad函数)