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 BufferedOutputStream(new FileOutputStream(result)));
    try {
      JarEntry entry = new JarEntry(DexFormat.DEX_IN_JAR_NAME);
      entry.setSize(dex.length);
      jarOut.putNextEntry(entry);
      try {
        jarOut.write(dex);
      } finally {
        jarOut.closeEntry();
      }
    } finally {
      jarOut.close();
    }

    return generateClassLoader(result, dexCache, parent);
  }
Generates a dex file and loads its types into the current process.

<h3>Picking a dex cache directory</h3>

The {@code dexCache} should be an application-private directory. If you pass a world-writable
directory like {@code /sdcard} a malicious app could inject code into your process. Most
applications should use this:

<pre>{@code
File dexCache = getApplicationContext().getDir("dx", Context.MODE_PRIVATE);
}</pre>

If the {@code dexCache} is null, this method will consult the {@code dexmaker.dexcache} system
property. If that exists, it will be used for the dex cache. If it doesn't exist, this method
will attempt to guess the application's private data directory as a last resort. If that fails,
this method will fail with an unchecked exception. You can avoid the exception by either
providing a non-null value or setting the system property.

@param parent the parent ClassLoader to be used when loading our generated types (if set,
    overrides {@link #setSharedClassLoader(ClassLoader) shared class loader}.
@param dexCache the destination directory where generated and optimized dex files will be
    written. If null, this class will try to guess the application's private data dir.
android/android_framework/dex-maker/src/main/java/com/android/dx/DexMaker.java